I have been tasked with finding out what is causing an issue with this bit of code:
public static ArrayList GetEthernetMacAddresses()
{
ArrayList addresses = new ArrayList();
ManagementClass mc = new ManagementClass("Win32_NetworkAdapter");
// This causes GetInstances(options)
// to return all subclasses of Win32_NetworkAdapter
EnumerationOptions options = new EnumerationOptions();
options.EnumerateDeep = true;
foreach (ManagementObject mo in mc.GetInstances(options)) {
string macAddr = mo["MACAddress"] as string;
string adapterType = mo["AdapterType"] as string;
if (!StringUtil.IsBlank(macAddr) && !StringUtil.IsBlank(adapterType))
{
if (adapterType.StartsWith("Ethernet")) {
addresses.Add(macAddr);
}
}
}
return addresses;
}
On our (Win2003) virtual servers, this works when run as part of a console application but not from a web service running on IIS (on that same machine).
Alternatively, I can use this code in a web service on IIS (on the virtual server) and get the correct return values:
public static string GetMacAddresses()
{
ManagementClass mgmt = new ManagementClass(
"Win32_NetworkAdapterConfiguration"
);
ManagementObjectCollection objCol = mgmt.GetInstances();
foreach (ManagementObject obj in objCol)
{
if ((bool)obj["IPEnabled"])
{
if (sb.Length > 0)
{
sb.Append(";");
}
sb.Append(obj["MacAddress"].ToString());
}
obj.Dispose();
}
}
Why does the second one work and not the first one?
Why only when called through an IIS web service on a virtual machine?
Any help would be appreciated.
UPDATE: After much telephone time with all different levels of MS Support, the've come to the conclusion that this is "As Designed".
Since it is on a driver level for the virtual network adapter driver, the answer was that we should change our code "to work around the issue".
This means that you cannot reliable test code on virtual servers unless you with the same code that you use on physical servers, since we can't guarantee that the servers are exact replicas...
-
Why are the two returning different results? It's possible that due to the different user accounts, you'll get different results running from the console and from a service.
Why does (1) fail and (2) work? Is it possible that a null result for adapterType return a null value? If so, would the code handle this condition?
-
Okay, so I wrote this code to test the issue:
public void GetWin32_NetworkAdapter() { DataTable dt = new DataTable(); dt.Columns.Add("AdapterName", typeof(string)); dt.Columns.Add("ServiceName", typeof(string)); dt.Columns.Add("AdapterType", typeof(string)); dt.Columns.Add("IPEnabled", typeof(bool)); dt.Columns.Add("MacAddress", typeof(string)); //Try getting it by Win32_NetworkAdapterConfiguration ManagementClass mgmt = new ManagementClass("Win32_NetworkAdapter"); EnumerationOptions options = new EnumerationOptions(); options.EnumerateDeep = true; ManagementObjectCollection objCol = mgmt.GetInstances(options); foreach (ManagementObject obj in objCol) { DataRow dr = dt.NewRow(); dr["AdapterName"] = obj["Caption"].ToString(); dr["ServiceName"] = obj["ServiceName"].ToString(); dr["AdapterType"] = obj["AdapterType"]; dr["IPEnabled"] = (bool)obj["IPEnabled"]; if (obj["MacAddress"] != null) { dr["MacAddress"] = obj["MacAddress"].ToString(); } else { dr["MacAddress"] = "none"; } dt.Rows.Add(dr); } gvConfig.DataSource = dt; gvConfig.DataBind(); }
When it's run on a physical IIS box I get this:
Same code on Virtual IIS server:
See a difference? It's on the first line. The virtual server doesn't return the "AdapterType" string. Which is why the original code was failing.
This brings up an interesting thought. If Virtual Server is supposed to be an "virtual" representation of a real IIS server, why doesn't it return the same values?
0 comments:
Post a Comment