Connection Monitoring

Mar 29, 2009 at 6:08 AM
Hi there,

First, impressive job.. thanks.

I've created a vpn connection but I don't know how to monitor its status..

Can you provide a code sample please ?
Mar 29, 2009 at 6:46 AM
Well, that depends on how you want to monitor it. If you simply want to poll the connection state you'd need to use the RasDialer component. If you would rather receive notifications of when that particular connection is disconnected you'll want to use the RasConnectionWatcher component along with setting the handle for the existing connection.

RasDialer dialer = new RasDialer();

foreach (RasConnection connection in dialer.GetActiveConnections())
    RasConnectionStatus status = connection.GetConnectionStatus();

That will give you basic information about the connectivity for each connection. The notification monitoring will be a bit harder.

private void StartMonitoring()
    RasDialer dialer = new RasDialer();

    RasHandle handle = null;
    foreach (RasConnection connection in dialer.GetActiveConnections())
        if (connection.EntryName == "My Connection")
            handle = connection.Handle;

    RasConnectionWatcher watcher = new RasConnectionWatcher();
    watcher.Disconnected += new EventHandler<RasConnectionEventArgs>(this.watcher_Disconnected);
    watcher.Handle = handle;
    watcher.EnableRaisingEvents = true;

private void watcher_Disconnected(object sender, RasConnectionEventArgs e);
    // This event is raised when that particular handle has disconnected.

The reason you want to provide the particular handle to the watcher is due to the fact that Windows will report all RAS disconnection notices if you do not. If that's not a problem for your situation you won't need to actually do it. Hopefully that'll give you some ideas to start from. One thing to be aware of, the Connection event on the RasConnectionWatcher receives notifications for all connections made on the machine, since you'd need a handle to monitor, and since a connection doesn't have a handle to monitor it cannot deal with it.

All of the components in the assembly are drag and drop capable within the VS IDE from your toolbox if you add them to it. I've been debating about creating an installer and HxS help documentation to aid developers with this, but for right now simple CHM documentation seems to suffice.
Mar 29, 2009 at 8:32 AM
Thanks Jeff

This was very helpfull, but one notice.. I couldn't use the RasConnectionWatcher in a class, I had to use it withing a form because it always gave me a null exception if used inside a class.

my code is:



handle As RasHandle = Nothing



For Each xconnection As RasConnection In xDialer.GetActiveConnections()



if xconnection.EntryName.ToUpper = RasVPN.Name.ToUpper Then


handle = xconnection.Handle


Exit For



End If



Next xconnection



Dim watcher As RasConnectionWatcher = New RasConnectionWatcher()



watcher.EnableRaisingEvents =



watcher.SynchronizingObject =



watcher.Handle = handle


AddHandler watcher.Disconnected, AddressOf watcher_Disconnected

This give an exception if used in a class, if in form it's ok.

any reason or it's just a bug ?


Mar 29, 2009 at 1:35 PM
Could be a bug, maybe dealing with the SynchronizingObject.

By the way, if you're using it on a form and not providing a synchronizing object you're going to get a cross thread exception thrown more than likely. Those events are raised on another thread (other than the UI thread) since Windows is the one raising it.

I'll take a look at it later today and see what's going on. It might be a problem with you using VB with it as well, not sure. Also, just a helpful tip - rather than calling ToUpper on the entry name creating another string, you should use string.Compare(xConnection.EntryName, RasVPN.Name, true) = 0 it's better for performance when doing case insensitive checks on strings. :)

I'll let you know what happens with my testing later.
Mar 29, 2009 at 2:23 PM
Thanks Jeff for the tip.. :)

I tried the code also in c#... same result..

my code also has:

System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = False
so the cross exception is ignored..

One more thing... the DOTRAS dll can't be called from an x64 application... it gives you the following exception

An incorrect structure size was detected.

if you call it from x86 application.. it works fine.



Mar 29, 2009 at 5:58 PM
Well, I think I might have spotted the structure size problem you're seeing. I looked over the structure definitions that the GetActiveConnections method uses, and the only possible problem I can see is the LONG type being used in the LUID structure. Not sure how I'm going to be able to test it, I don't have any 64 bit hardware to test it on unfortunately.

As for your other problem, it could be related to you setting the handle property after you've told the class to begin monitoring events for all connections, and then telling it to restart and monitor a specific connection handle. Once the EnableRaisingEvents property is set to true, it immediately starts monitoring.

I'll play around with it and see if I can replicate the problem.
Mar 29, 2009 at 6:12 PM
Which version of the assembly are you using, Win2k, XP, XP SP2, or Win2k8?

That'll help me narrow down where the struct size issue is coming from.
Mar 29, 2009 at 6:30 PM
Found the problem with the watcher component throwing an exception on you.

For now, just call the BeginInit and EndInit methods yourself - I'm checking in some changes to prevent this from happening when the object is created without using the designer.
Mar 29, 2009 at 6:32 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Mar 29, 2009 at 7:04 PM
The RasConnectionWatcher issue has been fixed as of changeset 30475. You'll need to be more specific about the other problem you were experiencing on the 64 bit platform, I can't tell which structure could be causing the problem. I have some ideas, but that's all.

I need to know which version of the compiled assembly you're using (WIN2K, WINXP, WINXPSP2, or WIN2K8). The structure size changes depending on which assembly version you're using.
Which method you're calling that's throwing the invalid structure size exception.

If you're using the PDBs I include with the assemblies, the call stack would be outstanding.
Mar 29, 2009 at 7:21 PM
Hi Jeff

I'm using WINXP SP2 

anyhow, I debugged the code... the error is raised when you call the GetActiveConnections method as you said..

Mar 29, 2009 at 7:30 PM

If you are interested, I've converted the code for DOTRAS to just for fun :)

it's working exactly as the C# version..

do u like me to send the project to you? if yes, tell me how to send it ?
Mar 29, 2009 at 8:09 PM
Edited Mar 29, 2009 at 8:24 PM
No thanks, having to maintain this thing in one language is plenty hehe.

Think I know how to fix the problem, it has to be the Luid implementation. Since you're obviously working with the source code, go into the Luid class and change the HighPart property to return an IntPtr type (you'll need to update the field to IntPtr as well) and see if that does anything. That's the only possible problem I can tell with that version of the assembly that would be causing that exception to be thrown.

Let me know what happens.

Edit: If you have access to C++, determining the size of long would help me out a lot as well. It seems that LONG can be a 32 or 64 bit value depending on which compiler was used.

DWORD l = sizeof(LONG);

I just need to know what the value gets set equals. I'm guessing it's going to be 8, even though the Windows SDK indicates the struct size is supposed to be comprised of two 32 bit values being 64 bits total. I may have to go report yet another portability bug to Microsoft involving RAS.
Mar 29, 2009 at 9:05 PM
Sorry, i dont' have C++

anyhow, I do think the problem is in getting the size in:



also please visit this link, may be it's helpfull


Mar 29, 2009 at 9:22 PM

Also check

Mar 29, 2009 at 9:29 PM

another question Jeff..

(Sorry for asking a lot, but i'm trying to work with you to make the DOTRAS a great product :)

i want to establish an L2TP vpn connection , but i don't want to use certificates , i want to use a pre-shared key... is that possible? if yes, please post me a sample


Mar 30, 2009 at 12:04 AM
Edited Mar 30, 2009 at 12:09 AM
I know where the problem is at already, and the only solution I have is to change the HighPart of the LUID structure to an IntPtr since Microsoft obviously didn't think of portability when the code was written (I'm guessing) before 64 bit systems existed. Now that 64 bit systems have become mainstream, their supposed 64 bit structure is now 96 bits. I'll just make the change and hope it works, the rest of the structure is correct. Besides, the majority of the people that write those answers on forums have absolutely no clue what they're talking about and cause more problems than they solve.

As for your question about establishing an L2TP connection, I don't know the answer to that. I'm not a network administrator, so I wouldn't want to give you a wrong answer. If you're just trying to setup the connection in a phone book, what I would suggest doing is creating the connection through Windows, make sure the connection works the way you want it to and then clone the entry in code. I wouldn't know where to start to setup a connection to do that in code. You have to bear in mind that the majority of the functionality of Windows I don't have the hardware here to test the software on, most of my unit tests just mock the RAS API and return values that I can test with.

If you want to clone the entry in code here is how you would do that:

RasPhoneBook pbk = new RasPhoneBook();

If you're saving the entry in the All User's profile you can use the Open method, if the entry resides in the current user's profile you'll need to call Open(true). Once the phone book has been opened you can continue.

RasEntry entry = pbk.Entries["Your L2TP Entry Name Here"];

From this point, look over the entry object and copy down all the properties Windows has set for you. From there you can set these same values in code to clone the entry programmatically.

Now that the entry properties have been copied, you'll need to create a new entry and add it to the phone book:

RasEntry newEntry = new RasEntry("Your New L2TP Entry Name");

// Set the properties to those you copied off the other entry.


Once the entry has been added to the phone book, it will become available for use for dialing, etc.
Mar 30, 2009 at 12:36 AM
Ok, go grab changeset 30488. It should take care of the problem you're seeing with the GetActiveConnections method.

Let me know whether it works or not, I have the work item kept open until I hear from you.
Mar 30, 2009 at 5:36 AM
Hi Jeff..

Unfortunately, this changeset doesn't work... It works as usuall in x86 but not in x64... still getting the incorrect structure size error (632).

Mar 30, 2009 at 3:36 PM
Edited Mar 30, 2009 at 3:38 PM
Ok, I came up with an idea to get this tested. You'll have to download and run a couple executables (I know, but you don't have C++ to compile it yourself) that will report to you the size of the RASCONN structure (which is the structure we're having problems with) along with the size of the LUID structure from the header files.

No idea if this is going to work, hopefully it will.

You'll want to go download changeset 30514 and unzip the file that's been included in the changeset. Once you have those extracted run each of them, and write down what they report back for both structure sizes on your 64 bit system. When you're done, report back those sizes here so I can do a bit more digging. As far as I can tell the structure sizes are correct, if they weren't it wouldn't be functioning on 32 bit systems. Most of the time I've only seen problems when I accidentally put an int in a place for a pointer, but according to the SDK those values are all ints.

The values you should see are:





If you're not aware how all of this works, the API determines which version of the structure you're using based on the size of the structure. If it can't determine which struct size you're using (typically the size is wrong) that's when you get error code 632 returned by the API which in turn throws the exception you're seeing.
Mar 30, 2009 at 3:59 PM
Ok, i ran the test

confirmed to:


but even , still the 632 error pops up !!!
Mar 30, 2009 at 4:09 PM
Edited Mar 30, 2009 at 4:16 PM
You're not using the WIN2K8 version of the DotRas assembly, you need to verify WINXPSP2 since that's the version of the assembly you're using. Each version of the DotRas assembly adds additional features that were supported by Windows, which in turn changes the structures.

What values are you seeing for the other 3 executables?
Edit: Something else that may help. You could try using the Windows 2000 version of DotRas (assuming you're not using XP specific features) to see if you're getting the exception thrown.
Mar 30, 2009 at 4:22 PM
Edited Mar 30, 2009 at 4:24 PM
Actually, I just thought of something.

1) Which operating system(s) are you using? If you're using more than one operating system to test the assembly, I'll need all of them.
2) Which operating system from question 1 is the 64 bit system?
3) Which compiled version of DotRas are you using? You should be using one of the following values:
     1.0.3371.42712 (WIN2K)
     1.0.3371.42783 (WINXP)
     1.0.3371.42855 (WINXPSP2)
     1.0.3371.42927 (WIN2K8)

This is assuming you're using the binaries that I compiled and uploaded for the release.
Mar 31, 2009 at 10:42 AM
Edited Mar 31, 2009 at 10:43 AM
I'm using the binaries that you compiled and uploaded for the release

I'm testing in Windows Vista Business x64, so my operating system is win2K8
Mar 31, 2009 at 2:34 PM
Edited Mar 31, 2009 at 2:36 PM
"Hi Jeff

I'm using WINXP SP2 

anyhow, I debugged the code... the error is raised when you call the GetActiveConnections method as you said..


I thought you said you were using Windows XP SP2, and you still haven't confirmed the structure sizes for the other operating systems.
Mar 31, 2009 at 9:09 PM
Hi again Jeff :)
Yes I was using WinXP sp2 when i sent the message.. Now i'm using another laptop with windows vista x64 business.

I tested on both and the structure size seems ok as u sent me.

So, my tests are now based on Win Vista OS.

I can test if you want on other operating systems, just tell me which one and i can arrange a pc with that specific OS..

Thanks Jeff.
Mar 31, 2009 at 9:24 PM
So you are now using Windows Vista with the WIN2K8 build on 32 bit and 64 bit systems and it's working correctly, or is the assembly still not functioning on the 64 bit system?
Apr 2, 2009 at 9:06 AM
Yes I'm using Windows Vista with the WIN2K8 build on 32 bit and 64 bit systems, but it is still not functioning on the 64 bit system, yet working nice on the 32 bit system.
Apr 2, 2009 at 1:58 PM
Well I've identified why the structure sizes matched up, I accidentally targetted the wrong platform when I built those tests you ran earlier. I had it targetted for the 32 bit platform by mistake and I just noticed I didn't install the 64 bit compiler for C++.

I'll have a new set of files for you to check the struct sizes for me soon.
Apr 2, 2009 at 2:33 PM
Edited Apr 2, 2009 at 2:45 PM
Ok, go dowload changeset 30609. There's an file sitting at the root of the folder with the new executables. They no longer run on my machine, so I know they're 64-bit now.

Make sure you report back the values from all 4 executables executed on the same 64-bit machine.

That will help me diagnose where the error is at in the structure. All 4 versions will execute just fine on the machine since the structures are always backwards compatible.

Apr 2, 2009 at 6:19 PM
Thanks Jeff

These are the results after running the executables:

RASCONN Size: 1360
LUID Size: 8

RASCONN Size: 1372
LUID Size: 8

RASCONN Size: 1372
LUID Size: 8

RASCONN Size: 1388
LUID Size: 8
Apr 2, 2009 at 7:06 PM
Edited Apr 2, 2009 at 7:13 PM
Outstanding, that narrowed it down to the WIN2K structure is where the problem is at. That is exactly what I needed!

Edit: Though after looking at the structure I'm even more confused than before. The only thing I can think of is the DWORD for the sub entry index isn't a DWORD after all. My RASCONN structure matches the SDK perfectly, and the size is still off.
Apr 2, 2009 at 7:37 PM
Ok, download changeset 30623 and try it again.

When you're checking it, you'll need to make sure a connection is active before calling the method to look at the data returned. Verify the properties on the object are what you expect. This is imperative, there's another DWORD field on the struct that could be causing the problem. I'm going with my gut on this and trying the subentry index field first. You'll want to run this assembly in both 32 and 64 bit modes to see whether the problem has been located. While in 32 bit, the data should be fine, when you switch to 64 bit here some symptoms you will see if I'm wrong:

The EntryName property will have the name of your entry shifted, and characters will have been removed.
The Device Name and Type properties will both be wrong.
The PhoneBook property will be wrong.

Basically, everything will be shifted 4 bytes.

Give that a go and let me know what happens.

Thanks for all your help trying to hunt this thing down, sheesh what a pain!
Apr 2, 2009 at 8:35 PM

Sorry Jeff, but that didn't work.. same problem in x64 and working fine in 32 bit.

entries, device names and phonebook are all ok not shifted.

I made double check that i'm using your changeset 30623 .. 100% sure.

Give another try and I can test again..

Apr 2, 2009 at 9:54 PM
You'll need my project as part of your solution in order to do this next test.

int size = Marshal.SizeOf(typeof(NativeMethods.RASCONN));

Stick a break point on that line in the RasHelper.GetActiveConnections method, and let me know what the size variable has been set to. It should indicate the size is 1388 (if you're using the WIN2K8 compilation symbol), if you haven't added the symbol it defaults to 1360.

The struct size should be correct now, changing the int to a pointer on a 64 bit system should make it 8 bytes wide instead of 4.
Apr 2, 2009 at 10:58 PM
The size is 1400 if I add the WIN2K8 compilation symbol

The size is 1368 if I don't add the WIN2K8 compilation symbol

Apr 3, 2009 at 4:26 AM
I've change the alignment for packing the struct, I'm hoping it fixes the problem.

Try changeset 30629 and let me know what happens. If it doesn't work, stick a break point where you did earlier and report back what size you receive for the different compilation symbols I've got defined.

Sorry for the problems, and thank you for all your help on this!

PS: I really wish I had a 64 bit system so I wouldn't need to keep asking you to do all this for me.
Apr 3, 2009 at 6:24 PM
Hi Jeff,

The size now is 1388 if I add WIN2K8 compilation symbol

The size is 1360 if I don't add the symbol

Still getting the same 632 error , incorrect structure size.  I'm using your source code and just made a test project for it.

btw, the DOTRAS creates the VPN connection with the specified properties successfully, but error 632 is raised only when you try to dial the connection. May be this helps?

Please feel free to ask for any kind of tests you may need to correct the problem.. :) I'm enjoying that.

Apr 3, 2009 at 7:27 PM
"Still getting the same 632 error , incorrect structure size.  I'm using your source code and just made a test project for it."

So you're getting the same error out of GetActiveConnections even though the structure size matches what the C++ header files say it should be? That makes no sense at all.

"btw, the DOTRAS creates the VPN connection with the specified properties successfully, but error 632 is raised only when you try to dial the connection. May be this helps?"

We'd better finish one problem at a time, more than likely the alignment problem is the same with the rest of the structures in the assembly since they're all at the default right now besides the RASCONN structure I changed yesterday.

Just to satisfy my own curiosity, what hardware are you using to test the 64 bit system? Processor make/model would be great if you don't mind sharing.
Apr 3, 2009 at 7:39 PM
No Jeff,

GetActiveConnections works fine and now I can get the active connections successfully..

It just raises an error when you try to dial the connection.

I used your console example, and the example was able to get the active connections, disconnect the active connection.. but it was not able to dial any connection..

got it?

My laptop is DELL 1720 Core2Duo, 2.5 GHz intel processor, 4 GByte RAM,, 250 GByte Hard Disk, Hardware virtualization enabled, 256 MByte Display card, bluetooth, wireless, blue ray...etc.
I'm doing the tests on this laptop, toegether with my kids pc which is 32 bit DELL precision.
I'm also testing on a virtaul 32 bit machine.
Also testing on a DELL Poweredge 2950 servers having 32 and 64 win2003 operating system.

Apr 3, 2009 at 7:49 PM
Now I see what you're saying, sorry bout that!

I'm pretty sure I know why the other structures are causing problems, but it's just weird that no one else has said anything till now other than you about the assembly not working on 64 bit systems. I wonder if the hardware architecture on those other machines people are (more than likely) using it on isn't having problems.

I know what's causing the error now across the other structs, I'll get them updated later tonight and get the changeset checked in. Check back in a few hours and it should be done.

Again, thank you for all your help.
Apr 3, 2009 at 7:55 PM
Thanks Jeff,

No doubt that if anybody uses the assemlby in 64 bit environment and the application is compiled for any cpu or x64 it will give an error.. I've tired this on standard  hardware (servers even) that are hosting a lot of native 64 bit applications (Win, SQL..etc).. so my guess that no body tests on an 64 bit environment with 64 bit compilation.. maybe they test with 32 bit compliation..

Anyhow, I'm glad that you knew now the problem and I'm definitely sure that you will solve it.. :)

Waiting for your changeset ....

Apr 3, 2009 at 9:17 PM
Yeah I wasn't really sure what might be causing your specific problems, if they were running it in 32 bit compatibility mode that might explain why I haven't heard anything. That's why I asked you for your hardware, I was curious if you were using an AMD processor that was throwing the alignments off slightly.

Anyway, I went through and verified the remaining structures in the NativeMethods class and checked all of their alignments. My guess is that's why you were experiencing troubles with the Dial method after we finally fixed the GetActiveConnections method.

Grab changeset 30651 and let me know what happens. It should fix any remaining issues you're having in that environment.
Apr 3, 2009 at 10:07 PM

Sorry Jeff, it is still the same.. I get an error when trying to dial the connection.. incorrect structure size

The size is 1388 if I add the WIN2K8 compilation symbol

The size is 1360 if I don't add the WIN2K8 compilation symbol


Apr 4, 2009 at 5:07 AM
Ok I should have it now. When I got home earlier this evening I installed my 64 bit Vista operating system on a VirtualBox emulating 64 bit hardware on my 32 bit machine.

I checked over a few more structs and found the issue. My math was right for the alignments on 32 bit systems, I just didn't take into account that pointers become 8 bytes wide on 64 bit systems which is why you saw that error. I went over the structures yet again and redid the math on any structs I hadn't changed the alignment on.

I tested the dial mechanism in the emulator and it did dial the connection, so it should work now.

Download changeset 30664 and let me know what happens. This should be the last time!
Apr 4, 2009 at 8:12 AM
Wonderfull job Jeff...

That did it.. no more errors on 64 bit ... great..

I'll keep testing this last build and I'll let you know as soon as possible..

Thanks for all the time and effort you have made to this discussion..

Best regards..
Apr 4, 2009 at 9:40 AM
Ok Jeff, everything seems to work ok on 64 bit :)

Just small hint about the code... I suggest that you don't use the following object names and events ( error, in) because these are reserved words in other dot net languages like Also don't use Resources name because it is also reserved, name it DotRasResources for instance..

Thanks for you excellent work and support.

P.S.:  I want to discuss with you the L2TP scenarios.. should i make a new discussion thread or continue here ?

Apr 4, 2009 at 1:44 PM
Good to hear everything is working on 64 bit now. Took a while but we managed to get it done!

If anything I've exposed publicly is causing problems for you I can most definitely consider renaming them. Just let me know which objects and/or members are causing problems specifically and I'll see what I can do. Most of the time I tried to stick with ErrorCode and ErrorMessage. However there are objects like DialCompletedEventArgs that inherit the Error name from AsyncCompletedEventArgs which is required for the asynchronous model I chose to use for dialing connections asynchronously. I suppose I could come up with a better name than Error for my common dialog error.

Resources is defaulted for Visual Studio by the default resource editor in the projects, the same goes for VB. That object is supposed to be kept internal anyway, so it doesn't matter what I name it.

What did you want to know about L2TP? Keep in mind, I'm not an expert on this subject matter I just wrote the assembly.
Apr 4, 2009 at 2:47 PM
Ok Jeff.

' If you need to pass the credentials into the dialer, create a new NetworkCredentials instance and pass


' it into either the Dial or BeginDial methods. This information is not stored anywhere within the dialer for



' obvious security reasons. If no credentials are provided, the dialer will use whatever is stored (if available).



Dim xCred As New System.Net.NetworkCredential(UserName, Password, Domain)



The previous code updates the credentials of the dialup connection (OR VPN) so that windows saves the username, password and domain. Once you dial that connection it uses whatever is stored (updated)... great and working fine.

There are types of VPN that uses L2TP IPSEC VPN... and on the IPSEC settings you enter a preshared key for authentication. (Please try to create a VPN connection like that with windows).

My question is:

How can I pass the preshared key to the entry through DotRas?


Apr 4, 2009 at 4:07 PM
Edited Apr 4, 2009 at 5:52 PM
Took a bit of digging in the SDK to find out where that functionality has been exposed.

You'll need to do 2 things:

1) On the RasEntry object, you MUST have UsePresharedKey set for the extended options. This means your application must use the WINXP, WINXPSP2, or WIN2K8 compilation directive. Windows 2000 does not support this feature.

        entry.ExtendedOptions |= RasEntryExtendedOptions.UsePresharedKey;

2) I'll be exposing something on the RasEntry object for UpdateCredentials to allow you to update the other values Windows allows.


Not sure how I'll expose it yet, though shouldn't take me too long to do it. All of the functionality is already in place inside the assembly, I just need to wire it up.

Keep checking back, it should be done today.
Apr 4, 2009 at 4:12 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Apr 4, 2009 at 5:15 PM
I wish they'd get rid of that notice to continue the discussion on the work item, it's rather annoying.

Maybe I don't want the discussion on the work item!
Apr 4, 2009 at 6:07 PM
:) I agree Jeff.. it's annoying
Apr 4, 2009 at 9:32 PM
Edited Apr 5, 2009 at 2:15 AM
Ok, I just finished checking in all the changes to add support for IPSec keys. Changeset 30679 (or later) has what you're looking for.

You'll still need to set the extended options if you want the dialer to use the value.

1) GetCredentials has been renamed to TryGetCredentials. Due to the pre-shared keys causing an exception to be thrown, the method signature has been changed.

        NetworkCredential credentials = null;
        if (entry.TryGetCredentials(RasPreSharedKey.Client, out credentials) && credentials != null)
            // The pre-shared key is stored in the password property of the credentials object.

2) UpdateCredentials contains a new overload for setting the pre-shared key values.

        entry.UpdateCredentials(RasPreSharedKey.Client, "12345");

3) ClearCredentials contains a new overload specifying which pre-shared key to clear.


The property you see in the VPN connection properties for IPSec security corresponds to the RasPreSharedKey.Client member.

Edit: Just a reminder, you will need to specify WINXP, WINXPSP2, or WIN2K8 compilation directive to enable these features.
Apr 14, 2009 at 4:28 AM
Hi there,

Great project!  I think .NET is a good platform, but it's missing some very important features.  Projects like DotRas does fill in the gap.

I am also trying to monitor my VPN connection using events.  I had tried using both RasDialer and RasConnectionWatcher events, but didn't get any notification in my event handler (I put breakpoint in there and manually disconnected the VPN).  Not sure if I am missing something obvious.  Here's my code:

                m_dialer.StateChanged += new EventHandler<StateChangedEventArgs>(m_dialer_StateChanged);
                m_vpnConnection = m_dialer.Dial(new System.Net.NetworkCredential(m_vpnUsername, m_vpnPassword));                                     RasHandle handle = null;
                foreach (RasConnection connection in m_dialer.GetActiveConnections())
                    if (connection.EntryName == "MyTestingVPNConnection")
                        handle = connection.Handle;

                RasConnectionWatcher watcher = new RasConnectionWatcher();
                watcher.SynchronizingObject = null;
                watcher.Connected += new EventHandler<RasConnectionEventArgs>(this.watcher_Connected);
                watcher.Disconnected += new EventHandler<RasConnectionEventArgs>(this.watcher_Disconnected);
                watcher.Handle = handle;
                watcher.EnableRaisingEvents = true;

Apr 14, 2009 at 5:04 AM
The Dial method is a synchronous call and will not raise any events by the component since it blocks the calling thread until the connection either completes or fails. If you want to receive state change notifications for the connection attempt you can simply use the DialAsync method. You can remove all of the RasConnectionWatcher code there since you won't need any of it (including the part to get the handle).

Also, just FYI - the handle returned by Dial and DialAsync is the connection handle - you don't need to check the active connections to find the handle and then set the Handle for the watcher.

watcher.Handle = m_vpnConnection;

That would have worked just as well with a lot less code. I plan on covering the RasConnectionWatcher class in my next YouTube video to hopefully address people using that component improperly.
Apr 14, 2009 at 5:50 AM
Thanks a lot for the quick response.  The code works perfectly now.