This project is read-only.

Re: RasConnectionState 24 on Win7 with WinXP build

Dec 1, 2011 at 6:31 AM
Edited Dec 1, 2011 at 6:33 AM

To continue the discussion from http://dotras.codeplex.com/workitem/14499

Why bother whether people can "start checking for that connection state" (ApplySettings) in an OS that does not support it (I cannot think of any scenario where not receiving the state in WinXP will break your code). It is more of a hassle for us when we get that "unknown" connection state in Win7, because now we cannot "handle" it in Win7 (without a hack). Besides, the XML comments already states that the state is only available in Win7, and developers can code accordingly (given that it would ever be necessary to depend on that specific state).

Alternatively, will it be acceptable to compile the framework with WINXP and WIN7 and then just make sure we do not use other Win7 features while the app is running on Windows XP? Or better, one can then dynamically decide at runtime whether certain features will be available to a user, depending on which OS is being used?

Dec 1, 2011 at 6:43 PM

Thanks for continuing the discussion here, I'm sure that anyone else who is interested in this conversation will find it much easier now.

I always welcome questions as to why I chose one design path over another, and there are a lot of challenges that were dealt with underneath the hood that many people may not be aware of when dealing with operating system level interoperability in a product like this. Let me start off by answering the second half of your question, and then I can circle around to the first once you have better understanding of what's going on.

Alternatively, will it be acceptable to compile the framework with WINXP and WIN7 and then just make sure we do not use other Win7 features while the app is running on Windows XP? Or better, one can then dynamically decide at runtime whether certain features will be available to a user, depending on which OS is being used?

If you are not aware, the way that Windows decides what features are available in RAS is the size of the structures passed to it from the caller. That's why when you use the Windows 7 assembly on a Windows XP machine, a RasException with an error code of 632 is thrown from pretty much everything. Since Windows expects a structure of say 100 bytes, and I'm passing in a structure of a size different than that of what it expects, it doesn't know what to do with it. If you look at the NativeMethods.cs file in the Internal namespace within the project you'll see that the structures get resized based on which operating system they're targetting. I had attempted what you asked in a previous version, but since each structure would either have to be written and parsed manually to a memory address during runtime or multiple structures would have to be maintained for each call (which was my previous approach) the amount of code that is needed vastly increases, which also increases the possible failure points. For stability, maintainability, and extensibility I chose the approach of building out multiple versions of the assembly targetting the operating system which supports those features.

Now back to your original question as to why I don't allow feature contamination between different versions of the product... I made a decision early on that if a particular object or member is available from a specific operating system forward, it would be exposed by DotRas in the same manner. If I had chosen to allow specific members to be available for earlier versions of RAS (enums for example), I would have to keep track of which enums I had made available to previous versions. That in turn would determine whether I put conditional compilation symbols in place in the components which makes it harder to maintain without constantly looking back at what I had done where. Some components for example can't be used between versions that because they supported different features. So for the sake of uniformity I opted to keep everything together for each version of RAS. Whether that is a bad choice is a matter of opinion, but it has served me well over the past 3 years of working on this product and I stand by my decision.

Your product has to be cross-platform compatible as well if you want to be able to support multiple operating systems from a single executable. Avoid writing code that interact with parts that change between platforms, or if you need to - determine how you want to build out multiple versions of your product that use different versions of the assembly. Hopefully I answered your questions!

- Jeff

Dec 5, 2011 at 7:08 AM

I guess there are allot of reasons why we choose certain design paths over others. But one fundamental "feature" of a framework is the abstraction of implementation details by providing a unified public interface to the consumer (hell, that's the reason why the .NET framework exists in the first place).

Lets forget about the size of structures (under the hood) and new features supported from certain OS versions. My question is: will all the public methods and properties (and thus the public classes) that are exposed by the WINXP build be available (as is - with the exception of entirely new methods, properties, classes and enums) in the WIN7 build without changing the public interface (methods, properties, classes and enums) provided by the WINXP build? Therefore allowing us to simply replace the DotRas.dll depending on which OS being used? Because, if the answers are 'yes', we could simply develop against the WINXP build and be assured that when we replace the DotRas.dll (build for Win7, Win8, etc.) it will still work without the need to rebuild our code (it would be like developing against .NET framework 2.0 and your application still works when the .NET framework 4 is installed).

Francois

Dec 5, 2011 at 3:53 PM

Will all the public methods and properties (and thus the public classes) that are exposed by the WINXP build be available (as is - with the exception of entirely new methods, properties, classes and enums) in the WIN7 build without changing the public interface (methods, properties, classes and enums) provided by the WINXP build?

Yes. The only thing that changes between versions is the addition of new members (properties, methods, enums, etc) to support new features of RAS for that operating system. In fact, all of my unit tests I've written to test interoperability between the platforms uses the same public members without changing any signatures to method calls.

I want to clarify something which seems to be a common misconception of how the platform interoperability works, so this may reduce the overall complexity of your build and deployment process...

Lets say you're using a RasDialer to dial a connection, and a RasPhoneBook to create a L2TP connection, and your app needs to work on Windows XP, Windows Vista, and Windows 7. If the code you wrote only interacts with pieces that do not change between versions, the DotRas.dll will never need to be replaced because all the structures used by Windows XP are also supported by all future versions of Windows. So lets say you want to display the connection states while the dialing attempt is in progress on a form... rather than displaying when ApplySettings happens, you might simply want to display some other string until the connection attempt completes rather than something specific to ApplySettings. Using this approach you'd only need to use the WINXP version of DotRas for all 3 operating systems.

Now I'm going to increase the complexity of your app and say that it needs to support the creation of both L2TP and SSTP type VPN connections. Since L2TP was introduced in Windows XP, those are always forward compatible... the problem is the new SSTP VPN connection type. Since SSTP was introduced in Windows 7 and since you want to maintain a single codebase, you will need to deal with how to get your product to build using both the WINXP and WIN7 versions of the assembly. The version of your product consuming the WINXP version of DotRas would be deployed to both the Windows XP and Windows Vista machines, while the WIN7 version would get deployed to the Windows 7 machines (which the Windows 7 version would include the additional SSTP support).

You do not need separate versions of your product unless your product needs to support features added between versions of Windows. If all you needed was support for L2TP connections, you could deploy your WINXP version on all 3 operating systems.

- Jeff

Dec 6, 2011 at 6:13 AM

Thanks Jeff. This makes sense.