#362322 - 04/08/2014 16:54
Windows programming: Listing enabled/disabled network adapters.
|
carpal tunnel
Registered: 20/12/1999
Posts: 31597
Loc: Seattle, WA
|
Wow, this one should be really easy, but it turns out it's not, thanks to Microsoft's API having an incorrect information return from one of their API functions. I'm having a programming problem and I'm wondering if anyone on the BBS has seen a solution to this one? Requirement: Programatically find out which network interfaces on the system (Wired, WiFi, Mobile Broadband, Bluetooth, 1394, whatever) are ENABLED or DISABLED (*not* connected/disconnected which must be ignored in this case, but rather, we need to know enabled or disabled). In other words, if I'm in the Windows GUI and I run the program: NCPA.CPL ...which brings up the network adapters control panel, I see a list of network adapters including all of the Wired, Bluetooth, WiFi, Mobile Broadband, and whatnot adapters. I can right-click on any of them and select DISABLE or I can select ENABLE. When one is disabled it is grayed out. In addition to the level of whether they are enabled or disabled, any given one of them can be connected or disconnected (or in the process of connecting). What I want to know is, regardless of whether they are disconnected or connected, I want to know, from any programming language (DOS script, C, C#, powershell, whatever, but preferably C# because it's what I'm working in right now) which ones are ENABLED or DISABLED. I need a list. That list should be every network adapter on the system, and whether, at the moment I run the function, their current state is ENABLED or DISABLED. Oh my God, do you have any idea how hard that is? You'd think it's easy. There are a thousand things on the internet saying "oh sure just do this...." Guess what? They're all WRONG because they all harken back to the same WMI interface command, and it's WRONG. IT LIES. Here's what they all boil back down to: Win32_NetworkAdapter class, property: NetEnabledIf you look at the dox for the NetEnabled property it says: NetEnabled Data type: boolean Access type: Read-only Indicates whether the adapter is enabled or not. If True, the adapter is enabled. You can enable or disable the NIC by using the Enable and Disable methods.
THIS IS A LIE. It only responds with the adapter's connected state not its enabled/disabled state. For example, if the adapter is enabled, but not connected to the network, this property will return FALSE. What's interesting is that the Enable and Disable methods indeed disable and enable the adapter as mentioned in the dox above, but the NetEnabled property has nothing to do with that. For example, you can have five network adapters, all of them disconnected (but enabled) and NetEnabled will be "FALSE" for all of them. Run ".Disable" on one of them and it will go gray in the network control panel, but all five will still read NetEnabled="FALSE". Run ".Enable" on the one you disabled, and it will ungray in the network control panel, but it will still read NetEnabled="FALSE" when queried with WMI. Okay, so how do I work around it? I've tried: - In .NET in C#, using System.Net.NetworkInformation namespace NetworkInterface class. This can get me a property of "OperationalStatus" which is "Up" or "Down" but again this is useless since it's only "Up" if it's connected. - The DOS command "netsh interface show interface". This WORKS and shows the correct "Admin State" of the interface as being enabled or disabled. However it's only for wired and Wifi networks, and does not include the other types of networks such as Mobile Broadband, which happens to be hyper-critical for my particular application. - The DOS command "wmic nic get NetConnectionID". This lists all network adapter names including the disabled ones. No information about disabled/enabled. - The DOS command "wmic nic get > somelistfile.txt". This lists all network adapters and all their WMI properties to a file. None of the columns in that file indicate disabled/enabled state. There is a column for our old friend NetEnabled which is still lying like a rug, as above. - Any variations in various languages I've seen all come back down to that WMI "NetEnabled" property. I.e., a lie. Any ideas? Has anyone run into this before?
|
Top
|
|
|
|
#362324 - 05/08/2014 02:30
Re: Windows programming: Listing enabled/disabled network adapters.
[Re: tfabris]
|
pooh-bah
Registered: 12/01/2002
Posts: 2009
Loc: Brisbane, Australia
|
No need to go calling it a lie multiple times as if MS is out to get you. This appears to work in Visual C# 2010 (using .NET 4.0) using the WMI NetEnabled property on my machine. It correctly shows enabled and disabled interfaces and is able to enable and disable them. http://code.msdn.microsoft.com/windowsapps/Disableenable-network-8112f642According to the documentation only Vista onwards is supported.
_________________________
Christian #40104192 120Gb (no longer in my E36 M3, won't fit the E46 M3)
|
Top
|
|
|
|
#362328 - 05/08/2014 14:49
Re: Windows programming: Listing enabled/disabled network adapters.
[Re: Shonky]
|
carpal tunnel
Registered: 20/12/1999
Posts: 31597
Loc: Seattle, WA
|
But it *does* lie. I downloaded and ran that example code and it lies like a rug. See the attached screen shot. Note in the screen shot that my wireless network connection is ENABLED, though it is not connected to anything at the moment. The example code that you linked presents it as DISABLED, which is wrong, as shown in the screen shot. If I connect it to a wireless network, then the example code presents it as ENABLED. Again, this is wrong. Connected is not the same thing as Enabled. Disconnected is not the same thing as Disabled. This Microsoft-supplied example code has the same problem as all of the other code I've found on the internet. Exactly as I stated in my original post. However, the page you linked did say one thing which I hadn't seen yet! This is very interesting: More Information The Win32_NetworkAdapter class is deprecated and use the MSFT_NetAdapter class instead. WMI class represents a network adapter: http://msdn.microsoft.com/en-us/library/windows/desktop/aa394216(v=vs.85).aspx I will investigate this MSFT_NetAdapter class!!!!!!!!
Attachments
Capture.PNG (4554 downloads)
|
Top
|
|
|
|
#362330 - 05/08/2014 15:37
Re: Windows programming: Listing enabled/disabled network adapters.
[Re: tfabris]
|
carpal tunnel
Registered: 20/12/1999
Posts: 31597
Loc: Seattle, WA
|
Hm. Can't get that class to work. Trying to use the namespace that it's in, I keep getting "Invalid Namespace" errors. I'm trying the example code here and it's not working, keeps erroring out on the GET statement saying that the namespace is wrong. http://wutils.com/wmi/ROOT/StandardCimv2...NetAdapter.html
|
Top
|
|
|
|
#362331 - 05/08/2014 15:52
Re: Windows programming: Listing enabled/disabled network adapters.
[Re: tfabris]
|
carpal tunnel
Registered: 20/12/1999
Posts: 31597
Loc: Seattle, WA
|
Sigh. None of the sample code is working because the namespace is wrong. In all cases in all languages. For example, the simple PowerShell command, typed into powershell, is supposed to work: Get-WmiObject MSFT_NetAdapter -Namespace root\StandardCimv2 It doesn't, says Invalid Namespace. All the code examples I see on the net say it should work. Why doesn't it work?
|
Top
|
|
|
|
#362332 - 05/08/2014 21:18
Re: Windows programming: Listing enabled/disabled network adapters.
[Re: tfabris]
|
pooh-bah
Registered: 12/01/2002
Posts: 2009
Loc: Brisbane, Australia
|
Ok I can see the problem now when the wireless adapter is enabled but not connected. I had to delete my access point setup.
MSFT_NetAdapter is Windows 8/Server 2012 and above only. Is that your problem?
BTW: to lie = to intentionally make a false statement
_________________________
Christian #40104192 120Gb (no longer in my E36 M3, won't fit the E46 M3)
|
Top
|
|
|
|
#362333 - 05/08/2014 21:46
Re: Windows programming: Listing enabled/disabled network adapters.
[Re: tfabris]
|
carpal tunnel
Registered: 08/07/1999
Posts: 5549
Loc: Ajijic, Mexico
|
It couldn't be something as dumb as this, could it? Minimum supported client Windows 8
Minimum supported server Windows Server 2012
Namespace \root\StandardCimv2 MOF NetAdapterCim.mof DLL NetAdapterCim.dll Naaahh... I didn't thing so. tanstaafl. edit: Never mind, I see that Shonky already addressed that.
Edited by tanstaafl. (05/08/2014 21:47)
_________________________
"There Ain't No Such Thing As A Free Lunch"
|
Top
|
|
|
|
#362334 - 06/08/2014 14:10
Re: Windows programming: Listing enabled/disabled network adapters.
[Re: Shonky]
|
carpal tunnel
Registered: 13/02/2002
Posts: 3212
Loc: Portland, OR
|
BTW: to lie = to intentionally make a false statement Having been making lots of false statements lately, playing make-believe with my 4yo daughter, I would add "with intent to deceive" to that definition.
|
Top
|
|
|
|
#362335 - 06/08/2014 15:41
Re: Windows programming: Listing enabled/disabled network adapters.
[Re: Shonky]
|
carpal tunnel
Registered: 20/12/1999
Posts: 31597
Loc: Seattle, WA
|
MSFT_NetAdapter is Windows 8/Server 2012 and above only. Is that your problem? Yep. Damn. I need to be able to reliably detect this on Windows 7 too. BTW: to lie = to intentionally make a false statement Seems real fucking deliberate to me. I'm really mad at whoever wrote that class right now. From a programmer's point of view, it really is lying. You design the code to a specification, and the docs state the spec. The docs specifically say the spec is "Enable" or "Disable", and yet the underlying code is deliberately reporting something entirely different from the spec. I'm pretty sure it's because someone else needed that class to report the connected state instead of the enabled state for some other thing somewhere else in Windows. So instead of adding or making use of a different field/parameter, they went the cheap/easy route and changed (deliberately) what the reported value was. They did this without going through the necessary steps of going back in and updating the spec and the docs. Probably because they wanted to avoid the work, overhead, and management red tape involved in doing so. If that's not intentionally lying, then I don't know what is. None of that matters of course. All it means is that I can't use that Win32_NetworkAdapter class to get the information I need. And the MSFT_NetAdapter won't work on one of my target platforms because it's too new. So now I need to figure out how to get that information. And I'm stumped. Somewhere in the Windows API there has to be a way to do it. The "Network Connections" screen is able to reliably show whether or not a given network adapter is disabled by graying it out. So what function is THAT program using to gather that information? That's what I need to find out.
|
Top
|
|
|
|
#362336 - 07/08/2014 05:47
Re: Windows programming: Listing enabled/disabled network adapters.
[Re: tfabris]
|
carpal tunnel
Registered: 18/01/2000
Posts: 5683
Loc: London, UK
|
So what function is THAT program using to gather that information? That's what I need to find out. Probably something in the SetupDiXxx family of functions. Good luck with that...
_________________________
-- roger
|
Top
|
|
|
|
#362337 - 07/08/2014 08:34
Re: Windows programming: Listing enabled/disabled network adapters.
[Re: tfabris]
|
pooh-bah
Registered: 12/01/2002
Posts: 2009
Loc: Brisbane, Australia
|
I don't agree with your theory that someone has gone the "cheap/easy route ... without ... updating the spec". Simply a bug. Anyway: This might help you: From a command line wmic nic where(ConfigManagerErrorCode=22)get Description,Index,NetConnectionID,PNPDeviceID,NetEnabled,ConfigManagerErrorCode Will return disabled network adapters only. My Wifi adapter is not returned regardless of connection as long as it is enabled so seems to do what you want/need. NetEnabled will show the incorrect status you are seeing. Then parse the text output. A bit clunky but workable. Will give you the full "dump". On my machine there are all sorts of "virtual" interfaces from various devices that have been plugged in over time.
_________________________
Christian #40104192 120Gb (no longer in my E36 M3, won't fit the E46 M3)
|
Top
|
|
|
|
#362338 - 07/08/2014 08:47
Re: Windows programming: Listing enabled/disabled network adapters.
[Re: tfabris]
|
pooh-bah
Registered: 12/01/2002
Posts: 2009
Loc: Brisbane, Australia
|
This might work better: wmic NIC where(NetConnectionStatus=0 OR NetConnectionStatus=2 OR NetConnectionStatus=7)get Description,Index,NetConnectionID,PNPDeviceID,NetEnabled,ConfigManagerErrorCode This should only filter in valid network interfaces. Stuff like VPNs should not show. Then, if ConfigManagerErrorCode is 22, the device is disabled.
_________________________
Christian #40104192 120Gb (no longer in my E36 M3, won't fit the E46 M3)
|
Top
|
|
|
|
#362339 - 07/08/2014 14:04
Re: Windows programming: Listing enabled/disabled network adapters.
[Re: Shonky]
|
carpal tunnel
Registered: 20/12/1999
Posts: 31597
Loc: Seattle, WA
|
BRILLIANT!
Yes, in my initial tests, the "ConfigManagerErrorCode" appears to be the correct indicator field.
Thank you!
How did you find that?
|
Top
|
|
|
|
#362340 - 07/08/2014 14:20
Re: Windows programming: Listing enabled/disabled network adapters.
[Re: tfabris]
|
carpal tunnel
Registered: 20/12/1999
Posts: 31597
Loc: Seattle, WA
|
Improving that slightly to:
wmic NIC where(NetConnectionID!=NULL)get NetConnectionID,NetEnabled,ConfigManagerErrorCode,Description
For my purposes, I think filtering on whether or not it's got a name is the correct thing. That gets me the list of everything that's visible in NCPA.CPL regardless of whether it's in the process of trying to connect to a carrier or something.
|
Top
|
|
|
|
#362341 - 07/08/2014 15:15
Re: Windows programming: Listing enabled/disabled network adapters.
[Re: tfabris]
|
carpal tunnel
Registered: 20/12/1999
Posts: 31597
Loc: Seattle, WA
|
Final demonstration batch file showing the difference between ConfigManagerErrorCode (correct) and NetEnabled (incorrect). I'm putting this in my "bag of tricks" batch file folder, posting here for posterity. I'm also going to be incorporating the ConfigManagerErrorCode=22 thing into the original C# program that I'm working on. Thanks again!
@echo off
::
:: ------------------------------------
:: GET LIST OF ENABLED OR DISABLED NICS
:: ------------------------------------
::
:: For WMI, you soon discover that the parameter
:: "NetEnabled" is a bad field, that parameter does
:: not list which NICS are enabled, it lists which
:: nics are connected. So how to determine if they
:: are enabled or not?
::
:: Turns out you have to look at a different field,
:: the ConfigManagerErrorCode, instead. If that is
:: 22 then the device is disabled.
::
:: Thanks to Christian ("Shonky") on the EmpegBBS
:: for finding this out!
::
::
set filename="%temp%\ListOfEnabledDisabledNics.txt"
set tempfilename="%temp%\TempListOfEnabledDisabledNics.txt"
echo List of NICs on this computer which are DISABLED or ENABLED. > %filename%
echo: >> %filename%
echo Note: Do not depend on the NetEnabled field, it is not true. >> %filename%
echo Look at ConfigManagerErrorCode instead. "22" means "Disabled". >> %filename%
echo: >> %filename%
echo: >> %filename%
echo --------- >> %filename%
echo DISABLED: >> %filename%
echo --------- >> %filename%
echo: >> %filename%
:: The command that actually lists the NICs. This is the list of the ones "equal to 22" which is the ones that are disabled.
:: NetConnectionID is the friendly name that you see in NCPA.CPL, only show ones where that value is not blank.
wmic NIC where(NetConnectionID!=NULL AND ConfigManagerErrorCode=22)get NetConnectionID,NetEnabled,ConfigManagerErrorCode,Description > %tempfilename% 2>&1
:: Filter out the unicode from the WMIC output (why the hell did they make it output in unicode?)
:: NICE TRICK: The DOS "Type" command filters out unicode.
type %tempfilename% >> %filename%
echo: >> %filename%
echo: >> %filename%
echo --------- >> %filename%
echo ENABLED: >> %filename%
echo --------- >> %filename%
echo: >> %filename%
:: This is the "not equal to 22" which is the ones that are enabled or otherwise not explicitly disabled.
wmic NIC where(NetConnectionID!=NULL AND ConfigManagerErrorCode!=22)get NetConnectionID,NetEnabled,ConfigManagerErrorCode,Description > %tempfilename% 2>&1
type %tempfilename% >> %filename%
echo: >> %filename%
:: Display the results in Notepad.
start "List of NICS" notepad.exe %filename%
|
Top
|
|
|
|
#362342 - 07/08/2014 16:42
Re: Windows programming: Listing enabled/disabled network adapters.
[Re: tfabris]
|
carpal tunnel
Registered: 18/01/2000
Posts: 5683
Loc: London, UK
|
I'm putting this in my "bag of tricks" batch file folder, posting here for posterity. You do know about github and gists, right?
_________________________
-- roger
|
Top
|
|
|
|
#362343 - 07/08/2014 16:47
Re: Windows programming: Listing enabled/disabled network adapters.
[Re: Roger]
|
veteran
Registered: 25/04/2000
Posts: 1525
Loc: Arizona
|
You do know about github and gists, right? I am looking forward to the future post about deja vu when Tony goes Googling to solve this problem and find the answer on this board in his post again
|
Top
|
|
|
|
#362344 - 07/08/2014 19:20
Re: Windows programming: Listing enabled/disabled network adapters.
[Re: Tim]
|
carpal tunnel
Registered: 20/12/1999
Posts: 31597
Loc: Seattle, WA
|
I am looking forward to the future post about deja vu when Tony goes Googling to solve this problem and find the answer on this board in his post again Seriously. If this BBS ever goes dark, there will be a great disturbance in The Force.
|
Top
|
|
|
|
#362345 - 07/08/2014 19:20
Re: Windows programming: Listing enabled/disabled network adapters.
[Re: Roger]
|
carpal tunnel
Registered: 20/12/1999
Posts: 31597
Loc: Seattle, WA
|
You do know about github and gists, right? wink I do, but haven't used them. Probably should start.
Edited by tfabris (07/08/2014 19:21)
|
Top
|
|
|
|
#362346 - 08/08/2014 07:24
Re: Windows programming: Listing enabled/disabled network adapters.
[Re: tfabris]
|
pooh-bah
Registered: 12/01/2002
Posts: 2009
Loc: Brisbane, Australia
|
BRILLIANT!
Yes, in my initial tests, the "ConfigManagerErrorCode" appears to be the correct indicator field.
Thank you!
How did you find that? Some google and some minor work with the wmic command. Glad it worked. Still a bit clunky but if it works well enough then great.
_________________________
Christian #40104192 120Gb (no longer in my E36 M3, won't fit the E46 M3)
|
Top
|
|
|
|
#362349 - 08/08/2014 14:05
Re: Windows programming: Listing enabled/disabled network adapters.
[Re: Shonky]
|
carpal tunnel
Registered: 20/12/1999
Posts: 31597
Loc: Seattle, WA
|
The only clunky part is using the DOS command line WMIC. But that's just an example to demonstrate the field values. For the actual code I was writing, which was in C# and was making WMI queries directly, it wasn't clunky at all.
I already had a C# function that was querying the NetEnabled property and getting the wrong answer. I merely had to change that to querying the ConfigManagerErrorCode property to get the right answer, and I was done. Not clunky at all.
|
Top
|
|
|
|
#362353 - 09/08/2014 02:09
Re: Windows programming: Listing enabled/disabled network adapters.
[Re: tfabris]
|
pooh-bah
Registered: 12/01/2002
Posts: 2009
Loc: Brisbane, Australia
|
Ah OK. Cool.
_________________________
Christian #40104192 120Gb (no longer in my E36 M3, won't fit the E46 M3)
|
Top
|
|
|
|
|
|