【问题标题】:Virtual Server IIS WMI Problem虚拟服务器 IIS WMI 问题
【发布时间】:2009-02-13 22:43:52
【问题描述】:

我的任务是找出导致这段代码出现问题的原因:

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;
}

在我们的 (Win2003) 虚拟服务器上,当作为控制台应用程序的一部分而不是从运行在 IIS 上的 Web 服务(在同一台机器上)运行时,它可以工作。

或者,我可以在 IIS(虚拟服务器上)的 Web 服务中使用此代码并获得正确的返回值:

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();
    }
}

为什么第二个有效,第一个无效?

为什么只在通过虚拟机上的 IIS Web 服务调用时?

任何帮助将不胜感激。


更新:在与所有不同级别的 MS 支持打了很多电话之后,我们得出结论,这是“按设计”。

由于它是虚拟网络适配器驱动程序的驱动程序级别,因此我们应该更改代码“以解决问题”。

这意味着您无法在虚拟服务器上可靠地测试代码,除非您使用在物理服务器上使用的相同代码,因为我们无法保证服务器是精确的副本...

【问题讨论】:

  • 第一个会导致什么错误?
  • 没有错误,只是一个空的ArrayList。

标签: web-services iis wmi virtual-machine


【解决方案1】:

好的,所以我写了这段代码来测试这个问题:

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();

}

当它在物理 IIS 机器上运行时,我得到以下信息: Physical IIS server http://img14.imageshack.us/img14/8098/physicaloutput.gif

虚拟 IIS 服务器上的相同代码: Virtual server http://img25.imageshack.us/img25/4391/virtualoutput.gif

看到区别了吗?第一行。虚拟服务器不返回“AdapterType”字符串。这就是原始代码失败的原因。

这带来了一个有趣的想法。如果虚拟服务器应该是真实 IIS 服务器的“虚拟”表示,为什么它不返回相同的值?

【讨论】:

    【解决方案2】:

    为什么两者返回不同的结果?由于用户帐户不同,您可能会从控制台和服务中获得不同的结果。

    为什么 (1) 失败而 (2) 有效? adapterType 的 null 结果是否可能返回 null 值?如果是这样,代码会处理这种情况吗?

    【讨论】: