WLAN Programming How-To Tips and Tricks Including Using It in C#
Questions concerning the wireless local area network APIs have been coming up a lot recently often in the context of using them from C#. You'll find an example C# WinForms application that allows you to see the almost all of the wireless network APIs in action at the end of this post. The WLAN APIs facilitate the enumeration, configuration, and management of WiFi on Windows Operating Systems. Here are just a fraction of things that the WLAN APIs allow a developer to do programmatically:
- Connect to a wireless network
- Disconnect from a wireless network
- Modify the behavior of the automatic wireless configuration module
- Start or stop a locally hosted wireless network
- Connect to or disconnect from a WiFi Direct device
- Query the properties of any of the above
- Read, Modify, and Create profiles that control the settings for a wireless network
- Create temporary profiles that can be used without making them available for display to the end user
The WLAN APIs follow the same general pattern of proper use for regular WiFi, WiFi Direct, and hosted wireless networks shown here:
- A handle/session is opened using WlanOpenHandle.
- Operations are performed as desired for the specific technology or technologies.
- The opened handle/session is closed using WlanCloseHandle.
The rest of this post is going to focus on the APIs for wireless networks. If you're interested in hearing more about the other technologies, please let me know in the comments section at the bottom of the page. Wireless networks are interacted with using a specific interface which typically ultimately represents a piece of hardware such as a wireless networking card. A collection of wireless network interfaces is obtained through the use of the WlanEnumInterfaces function. Most subsequent operations, such as managing profiles, connect or disconnecting from networks, etc. are performed against one of the specific interfaces. The one real exception is change monitoring. Change monitoring takes places for everything at the session/handle level. All of this functionality lends itself to wrap pretty easily into managed objects. You'll find the specific implementation details of what is below in the example code, but here's a basic summary of how things would roughly shape out as objects taken from the implementation of the example code:
WlanNative - Class that encapsulates the session/handle, provides access to a collection of WlanNativeInterface objects, controls whether or not to be listening for changes, and provides an event that can be subscribed to in order to receive change notifications
WlanNativeInterface - Class that encapsulates a specific wireless interface
Methods: Scan for available wireless networks, connect to a wireless network using an existing or temporary profile, disconnect from a wireless network, retrieve a profile, change a profile, change EAP or customer user data outside of a direct profile change, how the system profile edit dialog for a profile (there are a few other things that could be retrieved here as well)
Properties: Collection of wireless profiles as WlanNativeProfile objects, Collection of available wireless networks as WlanNativeNetwork objects, Interface Guid, Description, Autoconfiguration setting, background scan enabled, collection of physical radio state objects (not shown in this summary), collection of basic service sets objects (not shown in this summary), Interface state, currently used profile, current authentication algorithm, current cipher algorithm, Collection of supported authentication algorithms associated with their supported cipher algorithms as objects (not shown in this summary - one for infrastructureor adhoc), channel number, OneX enabled or disabled, Security enabled or disabled, Media streaming mode enabled or disabled, operation mode, safe mode support, certified for safe mode, and received signal strength (there are a few other things that could be retrieved here as well)
WlanNativeProfile - Class that encapsulates a specific wireless profile
Methods: All of the editing/deleting methods available for WlanNativeInterface that apply to the profile
Properties: Profile Name, UserProfile, GroupPolicyProfile
WlanNativeNetwork - Class that represents a specific wireless network
Properties: Connectable, Collection of Basic Service Set IDs, Name, SSID, BSS Type, Why it's not connectable if it's not, Signal strength, default authentication algorithm, default cipher algorithm, Collection of physical types, Security enabled
Here are a few concepts worth remembering that I've seen come up multiple times:
- Be sure to set profiles, EAP data, etc. with the all users flag set if you want the change to show up for other users. If you're not running in the same context as the user, e.g. a different session or user with code executing as a service, you need to do this in order for the changes to be used by the user.
- EAP and custom user data can be set in a profile directly. This is often more efficient than keeping up with them separately.
- Scanning for networks returns immediately and isn't additive most of the time; wait for the change event to indicate scanning is finished if you need all the networks
- Verify that profile settings are compatible with the interface by looking at the authorization types and their associated cipher algorithms by querying the interface
- Functions that take a parameter for the contents of a temporary profile want a string containing XML not a filename whose contents contains XML
- Use WlanFreeMemory properly to prevent memory leaks
- Use WlanUIEditProfile to let an end user edit a profile with the standard Windows dialog
Here are a couple screenshots of the example program: