- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在尝试使用 p/invoke setupapi 调用获取给定网络适配器的 PnPDeviceId,但没有成功。我不情愿地决定使用 WMI,就像这样:
public static string GetPnpDeviceId(string mac)
{
ManagementObjectCollection mo = Management.GetCollection("Win32_NetworkAdapter", "PNPDeviceID", "MACAddress = '" + mac + "'");
return GetFirstValueString(mo, "PNPDeviceID");
}
public static ManagementObjectCollection GetCollection(string WMIClass, string WMISelect="*", string WMIWhere="")
{
string qry = "SELECT " + WMISelect + " FROM " + WMIClass + (WMIWhere == "" ? "" : " WHERE " + WMIWhere);
ObjectQuery oq = new System.Management.ObjectQuery(qry);
ManagementObjectSearcher query = new ManagementObjectSearcher(oq);
ManagementObjectCollection queryCollection = query.Get();
return queryCollection;
}
public static string GetFirstValueString(ManagementObjectCollection queryCollection, string WMIValue)
{
foreach (ManagementObject mo in queryCollection)
{
object o = mo[WMIValue];
return (string)o;
}
return "";
}
p/invoke api 似乎很复杂,但为这样一个简单的调用加载管理类(尤其是 Win32_NetworkAdapter)的开销似乎过大。任何人都可以告诉我即使使用 p/invoke 这是否可行,或者更好的是仍然告诉我在哪里可以找到 api 调用中的值,我将从那里开始。
最佳答案
好的,我自己解决了。这是很多代码,但性能值得恕我直言。WMI 调用每次大约需要 800 毫秒,而 pinvoke 调用大约需要 25 毫秒。无论如何,这是代码(粗略且准备好的评论很少):
class NetPnP
{
internal static Guid GUID_DEVINTERFACE_NET = new Guid("CAC88484-7515-4C03-82E6-71A87ABAC361");
public static string GetPnPDeviceId(NetworkInterface ni)
{
Guid classGuid = GUID_DEVINTERFACE_NET;
IntPtr hwndParent = IntPtr.Zero;
Int32 flags = Win32DeviceMgmt.DIGCF_DEVICEINTERFACE | Win32DeviceMgmt.DIGCF_PRESENT;
IntPtr pDevInfoSet = IntPtr.Zero;
IntPtr pNewDevInfoSet = IntPtr.Zero;
try
{
pNewDevInfoSet = Win32DeviceMgmt.SetupDiGetClassDevs(ref classGuid, IntPtr.Zero, hwndParent, flags);//, pDevInfoSet, strMachineName, IntPtr.Zero);
if (pNewDevInfoSet == IntPtr.Zero)
{
Logger.Log("Failed to get device information list");
return "";
}
Int32 iRet;
Int32 iMemberIndex = 0;
do
{
Win32DeviceMgmt.SP_DEVINFO_DATA devInfoData = new Win32DeviceMgmt.SP_DEVINFO_DATA();
devInfoData.ClassGuid = Guid.Empty;
devInfoData.DevInst = 0;
devInfoData.Reserved = UIntPtr.Zero;
devInfoData.cbSize = Marshal.SizeOf(devInfoData);
iRet = Win32DeviceMgmt.SetupDiEnumDeviceInfo(pNewDevInfoSet, iMemberIndex, ref devInfoData);
if (iRet == 0)
{
Int32 iLastError = Win32DeviceMgmt.GetLastError();
if (iLastError == Win32DeviceMgmt.ERROR_NO_MORE_FILES)
{
//Console.WriteLine("No more devices in list");
break;
}
else
{
iMemberIndex++;
continue;
}
}
string desc = GetDevicePropertyString(pNewDevInfoSet, devInfoData, SetupDiGetDeviceRegistryPropertyEnum.SPDRP_DEVICEDESC);
if (ni.Description.Equals(desc)) return GetDeviceInstanceId(pNewDevInfoSet, devInfoData);
string friendly = GetDevicePropertyString(pNewDevInfoSet, devInfoData, SetupDiGetDeviceRegistryPropertyEnum.SPDRP_FRIENDLYNAME);
if (ni.Description.Equals(friendly)) return GetDeviceInstanceId(pNewDevInfoSet, devInfoData);
iMemberIndex++;
} while (true);
return "";
}
finally
{
Win32DeviceMgmt.SetupDiDestroyDeviceInfoList(pNewDevInfoSet);
}
}
static String GetDeviceInstanceId(IntPtr DeviceInfoSet, Win32DeviceMgmt.SP_DEVINFO_DATA DeviceInfoData)
{
StringBuilder strId = new StringBuilder(0);
Int32 iRequiredSize = 0;
Int32 iSize = 0;
Int32 iRet = Win32DeviceMgmt.SetupDiGetDeviceInstanceId(DeviceInfoSet, ref DeviceInfoData, strId, iSize, ref iRequiredSize);
strId = new StringBuilder(iRequiredSize);
iSize = iRequiredSize;
iRet = Win32DeviceMgmt.SetupDiGetDeviceInstanceId(DeviceInfoSet, ref DeviceInfoData, strId, iSize, ref iRequiredSize);
if (iRet == 1)
{
return strId.ToString();
}
return String.Empty;
}
static String GetDevicePropertyString(IntPtr DeviceInfoSet, Win32DeviceMgmt.SP_DEVINFO_DATA DeviceInfoData, SetupDiGetDeviceRegistryPropertyEnum property)
{
byte[] ptrBuf = GetDeviceProperty(DeviceInfoSet, DeviceInfoData, property);
return ptrBuf.ToStrAuto();
}
static Guid GetDevicePropertyGuid(IntPtr DeviceInfoSet, Win32DeviceMgmt.SP_DEVINFO_DATA DeviceInfoData, SetupDiGetDeviceRegistryPropertyEnum property)
{
byte[] ptrBuf = GetDeviceProperty(DeviceInfoSet, DeviceInfoData, property);
return new Guid(ptrBuf);
}
static byte[] GetDeviceProperty(IntPtr DeviceInfoSet, Win32DeviceMgmt.SP_DEVINFO_DATA DeviceInfoData, SetupDiGetDeviceRegistryPropertyEnum property)
{
StringBuilder strId = new StringBuilder(0);
byte[] ptrBuf= null;
UInt32 RegType;
UInt32 iRequiredSize = 0;
UInt32 iSize = 0;
bool iRet = Win32DeviceMgmt.SetupDiGetDeviceRegistryProperty(DeviceInfoSet, ref DeviceInfoData,
(uint)property, out RegType, ptrBuf, iSize, out iRequiredSize);
ptrBuf = new byte[iRequiredSize];
iSize = iRequiredSize;
iRet = Win32DeviceMgmt.SetupDiGetDeviceRegistryProperty(DeviceInfoSet, ref DeviceInfoData,
(uint)property, out RegType, ptrBuf, iSize, out iRequiredSize);
if (iRet)
{
return ptrBuf;
}
return new byte[0];
}
}
public static class ByteArrayEx
{
public static string ToStrAuto(this byte[] bytes)
{
string ret = "";
IntPtr unmanagedPointer = Marshal.AllocHGlobal(bytes.Length);
try
{
Marshal.Copy(bytes, 0, unmanagedPointer, bytes.Length);
// Call unmanaged code
ret = Marshal.PtrToStringAuto(unmanagedPointer);
}
finally
{
Marshal.FreeHGlobal(unmanagedPointer);
}
return ret;
}
}
public class Win32DeviceMgmt
{
internal static Int32 ERROR_NO_MORE_FILES = 259;
internal static Int32 LINE_LEN = 256;
internal static Int32 DIGCF_DEFAULT = 0x00000001; // only valid with DIGCF_DEVICEINTERFACE
internal static Int32 DIGCF_PRESENT = 0x00000002;
internal static Int32 DIGCF_ALLCLASSES = 0x00000004;
internal static Int32 DIGCF_PROFILE = 0x00000008;
internal static Int32 DIGCF_DEVICEINTERFACE = 0x00000010;
internal static Int32 SPINT_ACTIVE = 0x00000001;
internal static Int32 SPINT_DEFAULT = 0x00000002;
internal static Int32 SPINT_REMOVED = 0x00000004;
[StructLayout(LayoutKind.Sequential)]
internal struct SP_DEVINFO_DATA
{
/// <summary>
/// Size of structure in bytes
/// </summary>
public Int32 cbSize;
/// <summary>
/// GUID of the device interface class
/// </summary>
public Guid ClassGuid;
/// <summary>
/// Handle to this device instance
/// </summary>
public Int32 DevInst;
/// <summary>
/// Reserved; do not use.
/// </summary>
public UIntPtr Reserved;
};
[StructLayout(LayoutKind.Sequential)]
internal struct SP_DEVICE_INTERFACE_DATA
{
/// <summary>
/// Size of the structure, in bytes
/// </summary>
public Int32 cbSize;
/// <summary>
/// GUID of the device interface class
/// </summary>
public Guid InterfaceClassGuid;
/// <summary>
///
/// </summary>
public Int32 Flags;
/// <summary>
/// Reserved; do not use.
/// </summary>
public IntPtr Reserved;
};
[DllImport("setupapi.dll")]
internal static extern IntPtr SetupDiGetClassDevsEx(ref Guid ClassGuid, [MarshalAs(UnmanagedType.LPStr)]String enumerator, IntPtr hwndParent, Int32 Flags, IntPtr DeviceInfoSet, [MarshalAs(UnmanagedType.LPStr)]String MachineName, IntPtr Reserved);
[DllImport("setupapi.dll", CharSet = CharSet.Auto)]
internal static extern IntPtr SetupDiGetClassDevs( // 1st form using a ClassGUID only, with null Enumerator
ref Guid ClassGuid,
IntPtr Enumerator,
IntPtr hwndParent,
int Flags
);
[DllImport("setupapi.dll")]
internal static extern Int32 SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);
[DllImport("setupapi.dll")]
internal static extern Int32 SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, IntPtr DeviceInfoData, IntPtr InterfaceClassGuid, Int32 MemberIndex, ref SP_DEVINFO_DATA DeviceInterfaceData);
[DllImport("setupapi.dll")]
internal static extern Int32 SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet, Int32 MemberIndex, ref SP_DEVINFO_DATA DeviceInterfaceData);
[DllImport("setupapi.dll")]
internal static extern Int32 SetupDiClassNameFromGuid(ref Guid ClassGuid, StringBuilder className, Int32 ClassNameSize, ref Int32 RequiredSize);
[DllImport("setupapi.dll")]
internal static extern Int32 SetupDiGetClassDescription(ref Guid ClassGuid, StringBuilder classDescription, Int32 ClassDescriptionSize, ref Int32 RequiredSize);
[DllImport("setupapi.dll")]
internal static extern Int32 SetupDiGetDeviceInstanceId(
IntPtr DeviceInfoSet,
ref SP_DEVINFO_DATA DeviceInfoData,
StringBuilder DeviceInstanceId,
Int32 DeviceInstanceIdSize,
ref Int32 RequiredSize);
/// <summary>
/// The SetupDiGetDeviceRegistryProperty function retrieves the specified device property.
/// This handle is typically returned by the SetupDiGetClassDevs or SetupDiGetClassDevsEx function.
/// </summary>
/// <param Name="DeviceInfoSet">Handle to the device information set that contains the interface and its underlying device.</param>
/// <param Name="DeviceInfoData">Pointer to an SP_DEVINFO_DATA structure that defines the device instance.</param>
/// <param Name="Property">Device property to be retrieved. SEE MSDN</param>
/// <param Name="PropertyRegDataType">Pointer to a variable that receives the registry data Type. This parameter can be NULL.</param>
/// <param Name="PropertyBuffer">Pointer to a buffer that receives the requested device property.</param>
/// <param Name="PropertyBufferSize">Size of the buffer, in bytes.</param>
/// <param Name="RequiredSize">Pointer to a variable that receives the required buffer size, in bytes. This parameter can be NULL.</param>
/// <returns>If the function succeeds, the return value is nonzero.</returns>
[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern bool SetupDiGetDeviceRegistryProperty(
IntPtr DeviceInfoSet,
ref SP_DEVINFO_DATA DeviceInfoData,
uint Property,
out UInt32 PropertyRegDataType,
byte[] PropertyBuffer,
uint PropertyBufferSize,
out UInt32 RequiredSize
);
// Device Property
[StructLayout(LayoutKind.Sequential)]
internal struct DEVPROPKEY
{
public Guid fmtid;
public UInt32 pid;
}
[DllImport("kernel32.dll")]
internal static extern Int32 GetLastError();
}
/// <summary>
/// Flags for SetupDiGetDeviceRegistryProperty().
/// </summary>
enum SetupDiGetDeviceRegistryPropertyEnum : uint
{
SPDRP_DEVICEDESC = 0x00000000, // DeviceDesc (R/W)
SPDRP_HARDWAREID = 0x00000001, // HardwareID (R/W)
SPDRP_COMPATIBLEIDS = 0x00000002, // CompatibleIDs (R/W)
SPDRP_UNUSED0 = 0x00000003, // unused
SPDRP_SERVICE = 0x00000004, // Service (R/W)
SPDRP_UNUSED1 = 0x00000005, // unused
SPDRP_UNUSED2 = 0x00000006, // unused
SPDRP_CLASS = 0x00000007, // Class (R--tied to ClassGUID)
SPDRP_CLASSGUID = 0x00000008, // ClassGUID (R/W)
SPDRP_DRIVER = 0x00000009, // Driver (R/W)
SPDRP_CONFIGFLAGS = 0x0000000A, // ConfigFlags (R/W)
SPDRP_MFG = 0x0000000B, // Mfg (R/W)
SPDRP_FRIENDLYNAME = 0x0000000C, // FriendlyName (R/W)
SPDRP_LOCATION_INFORMATION = 0x0000000D, // LocationInformation (R/W)
SPDRP_PHYSICAL_DEVICE_OBJECT_NAME = 0x0000000E, // PhysicalDeviceObjectName (R)
SPDRP_CAPABILITIES = 0x0000000F, // Capabilities (R)
SPDRP_UI_NUMBER = 0x00000010, // UiNumber (R)
SPDRP_UPPERFILTERS = 0x00000011, // UpperFilters (R/W)
SPDRP_LOWERFILTERS = 0x00000012, // LowerFilters (R/W)
SPDRP_BUSTYPEGUID = 0x00000013, // BusTypeGUID (R)
SPDRP_LEGACYBUSTYPE = 0x00000014, // LegacyBusType (R)
SPDRP_BUSNUMBER = 0x00000015, // BusNumber (R)
SPDRP_ENUMERATOR_NAME = 0x00000016, // Enumerator Name (R)
SPDRP_SECURITY = 0x00000017, // Security (R/W, binary form)
SPDRP_SECURITY_SDS = 0x00000018, // Security (W, SDS form)
SPDRP_DEVTYPE = 0x00000019, // Device Type (R/W)
SPDRP_EXCLUSIVE = 0x0000001A, // Device is exclusive-access (R/W)
SPDRP_CHARACTERISTICS = 0x0000001B, // Device Characteristics (R/W)
SPDRP_ADDRESS = 0x0000001C, // Device Address (R)
SPDRP_UI_NUMBER_DESC_FORMAT = 0X0000001D, // UiNumberDescFormat (R/W)
SPDRP_DEVICE_POWER_DATA = 0x0000001E, // Device Power Data (R)
SPDRP_REMOVAL_POLICY = 0x0000001F, // Removal Policy (R)
SPDRP_REMOVAL_POLICY_HW_DEFAULT = 0x00000020, // Hardware Removal Policy (R)
SPDRP_REMOVAL_POLICY_OVERRIDE = 0x00000021, // Removal Policy Override (RW)
SPDRP_INSTALL_STATE = 0x00000022, // Device Install State (R)
SPDRP_LOCATION_PATHS = 0x00000023, // Device Location Paths (R)
SPDRP_BASE_CONTAINERID = 0x00000024 // Base ContainerID (R)
}
关于c# - 是否可以在不使用 WMI 的情况下获取网络适配器的 PnPDeviceId?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20174169/
对于 Windows,我可以使用哪些与 WMI 的监视和系统管理功能类似的其他框架或编程语言? 最佳答案 最能与 WMI 的性能监控功能相媲美的是 SNMP (Simple Network Manag
我的客户有一个旧的基于 DOS 的应用程序,它将格式化的输出发送到打印机。我已禁用打印,因此假脱机文件仍保留在打印队列中。我想拿起这些假脱机文件并将它们转换为 PDF 格式(然后最好删除它们)。这可能
给定一个查询,例如 SELECT * FROM WIN32_PROCESS 有没有办法查询结果对象的返回列的名称? 将结果对象中的所有行写入文本文件,例如 最佳答案 Is there a way to
谷歌让我失望,我在 MSDN 上找不到它。 man wmi在 Windows shell 上不起作用... 我正在寻找可以查询的对象列表,以及如何构建查询。 使用 WMI 我的意思是查询语言来查询诸如
我使用 .Net Framework SDK 中的 MgmtClassGen.exe 为 BizTalk 工件(例如主机、主机实例等)生成一些 WMI 包装器类。 我正在使用 HostSetting.
我正在尝试使用 WMI 获取连接到 Windows XP 计算机的硬件打印机列表。我想要的与从 Win32_Printers 获取列表不同,因为我只想获取物理上以盒子形式存在的打印机,从而消除所有“打
我查看了“root\virtualization”命名空间中的几个对象,但我无法找到 Hyper-V 存储给定虚拟机配置文件路径的位置。我需要以编程方式获取此文件路径,或者至少只是给定虚拟机的主路径也
这些都驻留在 root\RSOP\Computer 命名空间中。我得到非空结果的唯一类是 RSOP_RegistryPolicySetting ,而那个只给了我 Windows 更新和系统还原配置的设
有没有办法通过 WMI 创建/删除磁盘分区?我已经能够挂载/卸载虚拟磁盘 (vhd) 并列出它们的分区。 最佳答案 据我所知,在 WMI 中无法创建/删除分区。您可能想查看 Shell Functio
是否有用于 WMI/WBEM 的 OLEDB 提供程序? 换句话说,有人可以通过以下方式访问 WMI: shell vbscript 中的 ADO ASP 脚本中的 ADO Win32 native
我正在尝试破译 SecurityCenter.productState WMI 命名空间中的 productState 属性。 例如,产品状态是一个整数:262144 - 然后您可以查看此文档页面,将
最近很多用户在使用电脑的时候发现了wmi provider host进程占用内存比较大,不知道这个进程到底是干什么的,能不能禁止,怎么禁止。下面来一起看看想想的介绍吧。 wmi provide
我很难过,似乎无法找到明确的答案。我正在尝试通过 WMI 获取网络适配器列表。我一直在使用的命令在我们办公室的几乎所有工作站上都运行良好,没有任何问题。昨天,问题。一台机器出故障。由于它直接在用户
首先,我想说谢谢你帮我解决这个问题。非常感谢您付出的时间和努力。 标题总结得很好,但我将提供一些细节。基本上,如果我使用 C# 提取操作系统版本,它会返回适用于 Windows 8 的结果 6.2,即
我正在检测我是否正在尝试与本地主机建立连接,并创建(或不创建)WMI 连接选项,如下所示: if (NetworkUtils.IsLocalIpAddress(machineName)) {
我们如何枚举所有网络连接,以便使用 WMI 提取 VPN 连接的 IP 地址?在 XP 上,Win32_NetworkAdapterConfiguration 工作正常,但在 Vista 上它似乎只枚
我想使用 WMI(在 C++ 中)来配置静态 IPv6 地址。 使用 EnableStatic 配置静态 IPv4 地址工作正常,它是名为 Win32_NetworkAdapterConfigurat
我用这里的安装程序安装了wmi http://timgolden.me.uk/python/wmi/index.html但我无法导入模块。 这是我的代码: import wmi c=wmi.WMI()
当我尝试这样做时 SetDynamicDNSRegistration(True) 它返回“68”,我在 MSDN WMI page 上查找过它它的意思是“输入参数无效”。 完整脚本 import wm
我尝试使用 convert-vhd 命令将 VHD 转换为 VHDX,但出现以下错误: The Hyper-V Management Tools could not access an expecte
我是一名优秀的程序员,十分优秀!