Click here to Skip to main content
Click here to Skip to main content

Network Assistant for mobile PCs

By , 21 Apr 2007
 

Introduction

I don't know about you, but one of the things that bores me the most about being a "MobilePC" user is that I have to do the same things again and again and again and again…

So, this little app is what I have done in an attempt to remove the pain of being a mobile user. Its only purpose is to react to changes in your network environment and try to set your preferences accordingly. Let's say, for the sake of the example, that you use your laptop in 3 distinct places (at home, at work, and in the bus). You certainly change your default printer about 99 times a week, probably swear about that …. proxy you have at work, etc.

Wouldn't it be cool if your laptop just adapted to your environment?

NB: this article is not about the code in itself, but about the application, and how to use it. The only "tricky" (but really easy) bit of code is about the Network Awareness API (see the corresponding paragraph).

Definitions

Some definitions about the terms that I will use in this article.

NetworkConfiguration

A network configuration is an environment in which your MobilePC can be. Examples of NetworkConfigurations are : « At Home », « At work », « At client X », « Disconnected ». A NetworkConfiguration is defined by its tests – which identifies the state of network settings which identifies the environment – and its netlets –which are commands to execute in order to configure the system.

Tester

A tester is a class that allows to determine if your MobilePC is in a NetworkConfiguration. Examples : « Is My PC connected to DHCP server 192.168.0.1 ?» A NetworkConfiguration is called « active » if all of it's tests pass.

Netlet

A netlet is a command that is executed when a NetworkConfiguration is activated or disactivated. Its purpose is to set the environment up, such as changing the default printer, mapping a network drive or moving files to the desktop/start menu.

How does it work?

A small, notification-area-based application runs in the background of your session and reacts to changes in your network environment. Using a set of rules/Testers, it selects from the configurations that you have set-up the one that is currently active, and configures your systems accordingly.

Let's say that you use your laptop in three environments: at home, at work, and on the bus (or anywhere else without a proper network connection); between those three environments, you may want to change some of your settings such as your default printer, the proxy used to connect to the Internet, etc. What you need is something like:

Home Office Everywhere else
(when disconnected)
Use my inkjet printer Use a big laser printer Print to PDF files
Connect to the internet through my ISP router Use my corporate proxy
Map Z: to \\family\share
Get shortcuts to my server or applications on my desktop

You just have to configure three distinct NetworkConfigurations, and try to define what distinguishes one from another. When you have set-up the conditions (Testers) that uniquely identifies one configuration, you may add one or more commands (Netlets) which will change the state of your system.

Home Office Everywhere else
(when disconnected)
When those conditions are met (Testers)
There is a network present There is a network present There is no network connection
My DHCP Server is 192.168.0.254 My DHCP Server is 10.0.38.253
My DNS suffix is mycompany.com
What to do ? (Netlets)
Change default printer to My Inkjet Change default Printer to \\Server\Printer2 Change default printer to PDFPrint
Map Drive Z: to \\family\share
Copy *.rdp to my Desktop
Set IE Proxy to 10.0.38.254

A netlet will change to the desired state when a configuration is activated and revert back to the previous state when needed, so you don't have to worry about removing the proxy on IE on the Home profile if it is not set by default.

The Network Awareness API

The core of this software is the Network Awareness API which is shipped with Windows XP & Vista. For managed users, this API is available thru the System.Net.NetworkInformation namespace. The NetworkChange static class in this namespace contains two interesting events:

  • NetworkAvailabilityChanged which is fired when your MobilePC connects (or disconnects) to any network
  • NetworkAddressChanged fired when any of your network adapters receives a new IP address.

Using these events, it's rather easy to make an application respond to network changes (NB: this is not the code used by the application, but a rather heavily stripped down version for easier understanding):

private class MyAssistant
{
 public void Initialize()
 {
  NetworkChange.NetworkAddressChanged +=
   new NetworkAddressChangedEventHandler(NetworkChange_NetworkAddressChanged);
 }
 bool IsConnected
 {
  get
  {
   return NetworkInterface.GetIsNetworkAvailable();
  }
 }
 void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
 {
  if (IsConnected)
   ChangeDefaultPrinter("MyInkjet");
  else
   ChangeDefaultPrinter("PDFPrinter");
 }
}

I've used the NetworkAddressChanged event because I need the IP Address to be set for some tests (on DHCP or DNS settings). This code sample introduces the other important class of this namespace NetworkInterface which allows getting the settings from your network cards (and other devices). For this application, we need to find if a particular DHCP or DNS is used, so we'll iterate through all of our network interfaces, get their IP-related parameters and look for a known server:

void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
{
 if (!IsConnected)
  ChangeDefaultPrinter("PDFPrint");
 else if(FindDhcp(IPAddress.Parse("192.168.0.254")))
  ChangeDefaultPrinter("MyInkjet");
 else if(FindDhcp(IPAddress.Parse("10.0.38.253")))
  ChangeDefaultPrinter(@"\\Server\Printer2");
}
private bool FindDhcp(IPAddress dhcpAddress)
{
 foreach (NetworkInterface card in NetworkInterface.GetAllNetworkInterfaces())
 {
  IPInterfaceProperties props = card.GetIPProperties();
  foreach (IPAddress cardDhcp in props.DhcpServerAddresses)
  {
   if (cardDhcp.Equals(dhcpAddress))
    return true;
  }
 }
 return false;
}

Configuration

All the configuration of this assistant is done by through an XML-based settings file which you can edit from your start menu (Start>All Programs>Network Assistant v0.5>Edit your NetworkConfigurations). It's format is rather simple:

  • Each NetworkConfiguration must be a child of the root Config element and must have a name attribute
  • A NetworkConfiguration should have 2 child elements: Tests and Netlets
  • In Tests, you can put one of the following elements:
    • IsConnected
    • DnsServer
    • DnsSuffix
    • DhcpServer
  • In Netlets, the following children are allowed:
    • DefaultPrinter
    • ConnectNetworkDrive
    • CopyFiles
    • IEProxy
    • (more netlets will be added later)

A test element (IsConnected, DnsServer…) always has the same format:

<TestName value="valueToTest" />
Test name Value parameter Remark
IsConnected "true" or "false" If you want the test to pass when a network is available use "true", and if you want to test if the MobilePC is in a disconnected state use "false"
DhcpServer IP address You must use an IP address (192.168.0.1). Using a computer hostname is not supported
DnsServer IP address (idem)
DnsSuffix DNS suffix Ex : "carbenay.info"

The Tests node for the Home configuration is:

<Tests>
 <IsConnected value="true" />
 <DnsServer value="192.168.0.1" />
</Tests>

The netlets have not the same "standard" parameter so each one is different.

NetletName Parameter Remarks
DefaultPrinter printerName="{PrinterName}"
CopyFiles sourceFolder="{Path}" The {Path} parameter can include environment variables (such as %USERNAME%, %APPDATA% …) and can also use: %DESKTOP% : path to the current user's desktop (more aliases will be added)
destinationFolder="{Path}" Idem
searchPattern="{SearchPattern}" i.e.: "*.rdp", "*.lnk"…
ConnectNetworkDrive localDrive="{DriveLetter}" Drive letter (in the format X:) on which to mount the network share
remotePath="{RemotePath}" Path to the network share in UNC format (i.e.: \\server\share)
OpenFirewallPort port="{PortNumber}" port number.
This netlet only works on Windows XP. Vista would require Privilege elevation protocol="{Protocol}" Protocol can be either "TCP" or "UDP"

For example: the Home configuration's Netlets element is shown below:

<Netlets>
 <DefaultPrinter printerName="MyInkjet" />
 <CopyFiles
  sourceFolder="%LOCALAPPDATA%\NetworkAwareAssistant\Home\CopyFiles\"
  destinationFolder="%DESKTOP%"
   searchPattern="*.rdp"
   />
 <ConnectNetworkDrive
    localDrive="J:"
    remotePath="\\FamilyServer\Share" />
</Netlets>

A future version of NetworkAssistant will include a Control Panel application, but for this first release, you'll have to edit your settings manually.

Extensibility

Extending this app is rather simple: you just have to create classes that implement INetlet, put your assembly in the application folder (or in the GAC), and add a reference to it in the NetworkAwareAssistant.xml file.

Implementing a netlet requires you to implement an interface with 5 methods (sample code comes from the ChangeDefaultPrinterNetlet class):

  • void Initialize(string configurationName, XmlElement config): called when the configuration file is parsed. The configurationName parameters will be set to the name of the parent NetworkConfiguration, and the config parameter will be the XmlNode of your Netlet in the file.

    public void Initialize(string stateName, System.Xml.XmlElement config)
    {
     if (config == null)
      throw new ArgumentNullException("config");
     _defaultToSet = config.GetAttribute("printerName");
    }

  • void Connect(): called when the NetworkConfiguration is activated. There you should perform whatever your Netlet is supposed to do.

    public void Connect()
    {
     if (string.IsNullOrEmpty(_defaultToSet))
      return;
     using (ManagementObjectSearcher sr = new ManagementObjectSearcher(
        "select * from Win32_Printer where default=1 or name=\""
            + _defaultToSet + "\""))
     {
      ManagementObject oldPrinter;
      ManagementObject newPrinter;
      string currentDefaultName;
      FindPrinters(sr,
       _defaultToSet,
       out oldPrinter,
       out newPrinter,
       out currentDefaultName);
      if (oldPrinter != newPrinter)
      {
       try
       {
        newPrinter.InvokeMethod("SetDefaultPrinter", new object[0]);
        _defaultToRestore = currentDefaultName;
       }
       catch (Exception e)
       {
       throw new Exception("Unable to set the default printer to " +
        _defaultToSet);
       }
      }
     }
    }

  • void Disconnect(): called when a NetworkConfiguration is deactivated. This method must revert the environment in its previous state if possible. In ChangeDefaultPrinterNetlet, this method is quite similar to Connect.

  • void SaveState(System.Xml.XmlElement elmToSaveTo): provides a way for the system to remember the current state of the NetworkConfiguration. This method (with Load) allows for the application to shutdown and restart. In this method you should put any data that you may need to restore the netlet to its current state.

    public void SaveState(System.Xml.XmlElement elmToSaveTo)
    {
        elmToSaveTo.SetAttribute("oldDefault", _defaultToRestore);
        elmToSaveTo.SetAttribute("newDefault", _defaultToSet);
    }

  • void LoadState(System.Xml.XmlElement elmToLoadFrom): Loads the netlet state from a previously saved state. These two methods are only meant to do some basic serialization: they should not (except if it really makes sense for your netlet) make any changes to the system.

    public void LoadState(System.Xml.XmlElement elmToLoadFrom)
    {
        _defaultToRestore = elmToLoadFrom.GetAttribute("oldDefault");
        _defaultToSet = elmToLoadFrom.GetAttribute("newDefault");
    }

When your class is ready, there are two more things to do:

  • Add a NetletAttribute to the class: the name parameter of this attribute will be used to identity your netlet's configuration nodes in the NetworkAwareAssistant.xml file.

    [Netlet("TraceConfigChange")]
    public class TraceChangeNetlet : INetlet
    {
    ...
    }
  • Add a reference to your assembly and class in NetworkAwareAssistant.xml by adding a new /Config/Assemblies/Add node and add your netlet to a NetworkConfiguration.

    <Config>
     <Assemblies>
      <Add name="MyExtensionAssembly"/>
     </Assemblies>
     ...
     <Netlets>
      <TraceConfigChange />
     <Netlets>
     ...
    </Config>

Here is the sample code for a Netlet that just writes a trace on Connect/Disconnect:

[Netlet("TraceConfigChange")]
public class TraceChangeNetlet : INetlet
{
 private string _currentConfig = null;
 public void Initialize(string stateName, System.Xml.XmlElement config)
 {
  _currentConfig = stateName;
 }
 public void Connect()
 {
  Trace.TraceInformation("NetworkConfiguration " + 
                    _currentConfig +" activated");
 }
 public void Disconnect()
 {
  Trace.TraceInformation("NetworkConfiguration " + 
                    _currentConfig +" de-activated");
 }
 public void LoadState(System.Xml.XmlElement elmToLoadFrom)
 {
 }
 public void SaveState(System.Xml.XmlElement elmToSaveTo)
 {
 }
}

History

  • 21 Apr 2007: First release
  • 25 Apr 2007: Added a command to open port in firewall for Windows XP (Vista firewall would need a privilege elevation). Thanks for suggesting this goes to sides_dale.

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication

About the Author

mcarbenay
Web Developer
France France
Member
I'm french, do I need to say more ?

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionHard Coded IP Addressesmembersides_dale22 Apr '07 - 15:38 
I have to admit I have not downloaded this and tried it yet, but it does look very useful.
 
From what I have read this seems to be sufficient for the average user. But to make this a great tool for power users there needs to be at least more things:
1. The ability to have a hardcoded IP address when on certain networks, this would include the DNS server, IP address, Gateway, special routes if needed, etc.
2. The ability to manipulate windows firewall settings per location (sometimes I like to have my ports open for file sharing, web server, etc, but on non-trusted networks I like to keep my ports locked tight)
 
These are just two things that I noted right off.
 
It looks like you base the location on the IP address of the DHCP server. For you to be able to add the functionality that I mentioned above you would need to have another type of network detection, if you would like to expand the app I could look into port detection or something.

AnswerRe: Hard Coded IP Addressesmembermcarbenay23 Apr '07 - 5:39 
Yes, as the matter of fact, I didn't really write a full fledged powertoy-wanabee, but you're right some more things would be great, and I'll try to write them whenever I find some free time :
- Windows firewall changer was one of the first on my todo list
- a file sync command would be great too
- a control panel applet to set everything up
 
On the fixed IP front, I wonder how could I detect the network ? Without a dhcp server I really just see two solutions to find on which network a mobilePC is :
- ask the user
- try every "hard coded" configuration one by one until one suitable is found
If you have a suggestion on that issue, I'd be more than happy to hear about it.
 
Michael CARBENAY
My Blog

GeneralRe: Hard Coded IP AddressesmemberGavin Roberts24 Apr '07 - 0:23 
You could try pinging the Gateway for each hardware configuration or use WMI.
GeneralRe: Hard Coded IP Addressesmembermcarbenay24 Apr '07 - 0:32 
Err...
 
I think we're not talking about the same thing...
What I'm wondering is how to automatically set the IP settings from a list of known configurations.
 
And I think you're just suggesting that I can use IP settings that you have already set (am I correct ?) to trigger the changes. If that's right, I've already thought of not using only DHCP server IP, but also DNS server IP and DNS suffix. The gateway IP will also be tested in the second release that I'm coding.
In fact in this version, you can combine 4 types of tests to discover what network you are using :
- Am I connected or not ?
- What's my DNS server IP ?
- What's my DHCP server IP ?
- What's my DNS suffix ?
 

 
Michael CARBENAY
My Blog

GeneralRe: Hard Coded IP AddressesmemberGavin Roberts24 Apr '07 - 0:37 
Even still, IIRC you should be able to set the Network Configuration using WMI.
GeneralRe: Hard Coded IP Addressesmembermcarbenay24 Apr '07 - 0:52 
Okay, so would this scenario correspond to what you want ?
 
- if I have a configured IP address, the app try to find which network you use by mean of DHCP, DNS, Pinging etc.
- if I don't have any configured IP, a notification ballon says "unable to find your network settings, click here to choose your network". If you click, you have a list of your different settings, click on one of them, and the Fixed IP settings are applied to your network configuration.
 
If so (and because that such a great idea), I'll try to write the code !
 
Michael CARBENAY
My Blog

GeneralRe: Hard Coded IP AddressesmemberGavin Roberts24 Apr '07 - 1:17 
Personally I have no use for this application, I thought I would just give my 2 cents worth.
 
At some point you will need to have some sort of Device Priority selection. Most laptops have 2 or more network devices, One usually wired and the rest being Wireless and Bluetooth.
 
The worrying part comes when you have more then one Network device in which the Configuration will work. So your wired network is plugged in and has got a connection (by DHCP or Static), but at the same time, your Wireless has found a SSID and has automatically connected to it, and by means it has also got a connection.
 
it could get extremely confusing.
GeneralRe: Hard Coded IP Addressesmembermcarbenay24 Apr '07 - 23:00 
Yes,
 
not to mention that you could have a PAN connection with a Bluetooth, wireless connection in device mode (simple connection between two wi-fi devices, without any access points), and so on.
 

 
Michael CARBENAY
My Blog

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 21 Apr 2007
Article Copyright 2007 by mcarbenay
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid