in

Platinum Bay

Peace, Love, and...

This Blog

Syndication


.NETicated

Location Switcher

I have finally got it, my Location Switcher.

First, some background. I use my laptop both at work, and at home. At work, I use a static IP and a second monitor @ 1024x768. At home, I use DHCP and a second monitor @ 1280x1024. So I wake up, go do some work, then go to work, change the settings, then go home and have to change them again. It wasn't long before this got REALLY annoying. For small utilities like this, I much prefer to build versus buy. It is fun. I figured there had to be a way to automate this process. It took a lot of digging around, but I finally got it. I now have an icon in the task tray, which has a context menu with the options I need. I originally had a Console app, but this just seemed easier.

The first menu item, Location, allows me to select a preconfigured location. When I go to work, I select Work, and it sets my static IP, and secondary monitor resolution. When I go home, it sets my network card to DHCP, and adjusts the second monitor. It is almost too easy. The Resolution item allows me to manually set specific resolutions for either the primary or secondary monitor. The Network option is not yet populated. Configure allows me to set up pre-defined configurations, like Work and Home. Finally Exit allows me to shut down the program in case I ever need to free up the minimal resources it is using because I am running low on the 2GB of memory I have installed.

Most of what I needed to do I found in the following WMI classes:

  • Win32_NetworkAdapter
  • Win32_NetworkAdapterConfiguration
  • MicrosoftDNS_Server

For the monitors, I had to dig into the Windows API, yuck. I ended up using three methods in the user32.dll library;

  • EnumDisplaySettings
  • ChangeDisplaySettingsEx
  • EnumDisplayDevices

For the configuration, I defined a schema (probably overkill), and used MSDataSetGenerator to generate a strongly-typed class. This allowed me to load a config from disk.

<?xml version="1.0" encoding="utf-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:cfg="http://tempuri.org/config.xsd" targetNamespace="http://tempuri.org/config.xsd" elementFormDefault="qualified">
   
<element name="config" type="cfg:tConfig" />
   
<complexType name="tConfig">
       
<choice maxOccurs="unbounded"> 
           
<element name="network" type="cfg:tNetwork" maxOccurs="unbounded" /> 
       
</choice
   
</complexType
   
<complexType name="tNetwork"
       
<sequence
           
<element name="nameservers" type="cfg:tNameservers" /> 
           
<element name="adapter" type="cfg:tAdapter" /> 
           
<element name="routes" type="cfg:tRoutes" nillable="true" maxOccurs="unbounded" /> 
           
<element name="display" type="cfg:tDisplay" nillable="true" maxOccurs="1" /> 
       
</sequence
       
<attribute name="id" type="string" /> 
       
<attribute name="name" type="string" /> 
   
</complexType
   
<complexType name="tAdapter"
       
<attribute name="type" type="cfg:tNetworkType" use="required" /> 
       
<attribute name="ipaddress" type="string" use="optional" /> 
       
<attribute name="subnet" type="string" use="optional" /> 
       
<attribute name="gateway" type="string" use="optional" /> 
   
</complexType
   
<complexType name="tNameservers"
       
<sequence
           
<element name="nameserver" type="cfg:tNameserver" nillable="true" maxOccurs="unbounded" /> 
       
</sequence
   
</complexType
   
<complexType name="tNameserver"
       
<simpleContent
           
<extension base="string" /> 
       
</simpleContent
    
</complexType
   
<simpleType name="tNetworkType"
       
<restriction base="string"
           
<enumeration value="static" /> 
           
<enumeration value="dynamic" /> 
       
</restriction
   
</simpleType
   
<complexType name="tRoutes"
       
<sequence
           
<element name="route" type="string" minOccurs="0" maxOccurs="unbounded" /> 
       
</sequence
   
</complexType
   
<complexType name="tDisplay"
       
<sequence minOccurs="0" maxOccurs="1"
           
<element name="h" type="int" minOccurs="0" maxOccurs="1" /> 
           
<element name="v" type="int" minOccurs="0" maxOccurs="1" /> 
       
</sequence
       
<attribute name="enabled" type="boolean" use="required" /> 
   
</complexType>
</schema>

So there it is. If I get any interest, I might publish the source code. There are still features to add. For example, I would love to have it auto-detect the network and automatically switch.

Published Apr 19 2007, 01:31 AM by Steve
Filed under: ,

Comments

April 26, 2007 8:40 PM

I do all of my development on my laptop. I call it my "mobile development server". Scott Swanson published

 

February 9, 2012 1:12 PM

brillant piece of information, I had come to know about your web-page  from my friend hardkik, chennai,i have read atleast 9 posts of yours by now, and let me tell you, your webpage gives the best and the most interesting information. This is just the kind of information that i had been looking for, i'm already your rss reader now and i would regularly watch out for the new posts, once again hats off to you! Thanx a million once again, Regards, <a href="http://lifequotes99.com">quote of life</a>

 

Leave a Comment

(required )  
(optional )
(required )  
Add

About Steve

Steve Andrews is an independent consultant, INETA speaker, and Microsoft MVP for Visual Studio ALM. He has been working in technology for over ten years focusing on custom application development and Application Lifecycle Management. Steve is also Microsoft and IBM certified and a community fanatic having led sessions at nearly 100 events across North America. When he's not developing software solutions or engaging with the community about software technology, Steve is a closet singer and songwriter and plays the guitar and keys. Occasionally, Steve even gets to sleep. Occasionally.
Powered by Community Server (Commercial Edition), by Telligent Systems
© Platinum Bay | Some Rights Reserved Creative Commons License

Disclaimer: The information in this weblog is provided "AS IS" with no warranties, and confers no rights. This weblog does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my opinion. Feel free to challenge me, disagree with me, or tell me I'm completely nuts in the comments section of each blog entry, but I reserve the right to delete any comment for any reason whatsoever (abusive, profane, rude, or annonymous comments) - so keep it polite, please.