如何从DEV_BROADCAST_DEVICEINTERFACE和设备实例ID获取友好设备名称

sni*_*ker 11 c# winapi guid device-instance-id

我已经使用RegisterDeviceNotification注册了一个窗口,并且可以成功接收DEV_BROADCAST_DEVICEINTERFACE消息.但是,dbcc_name返回的结构中的字段始终为空.我所拥有的结构定义如下:

[StructLayout(LayoutKind.Sequential)]
public struct DEV_BROADCAST_DEVICEINTERFACE
{
    public int dbcc_size;
    public int dbcc_devicetype;
    public int dbcc_reserved;
    public Guid dbcc_classguid;
    [MarshalAs(UnmanagedType.LPStr)]
    public string dbcc_name;
}
Run Code Online (Sandbox Code Playgroud)

我正在使用WM_DEVICECHANGE消息Marshal.PtrToStructureLParam.

这应该有用吗?

或者甚至更好......是否有另一种方法可以在连接时获取设备的名称?

编辑(02/05/2010 20:56GMT):

我发现如何通过执行以下操作来填充dbcc_name字段:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DEV_BROADCAST_DEVICEINTERFACE
{
    public int dbcc_size;
    public int dbcc_devicetype;
    public int dbcc_reserved;
    public Guid dbcc_classguid;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=255)]
    public string dbcc_name;
}
Run Code Online (Sandbox Code Playgroud)

但我仍然需要一种从int dbcc_name获取"友好"名称的方法.它看起来如下:

\?\ USB#VID_05AC&PID_1294​​&MI_00#0#{6bdd1fc6-810f-11D0-BEC7-08002BE2092F}

而我真的只想说"苹果iPhone"(在这种情况下就是设备).

sni*_*ker 10

好吧,如上所述,我发现了如何正确填充dbcc_name.我发现这是获取设备名称的最简单方法:

private static string GetDeviceName(DEV_BROADCAST_DEVICEINTERFACE dvi)
{
    string[] Parts = dvi.dbcc_name.Split('#');
    if (Parts.Length >= 3)
    {
        string DevType = Parts[0].Substring(Parts[0].IndexOf(@"?\") + 2);
        string DeviceInstanceId = Parts[1];
        string DeviceUniqueID = Parts[2];
        string RegPath = @"SYSTEM\CurrentControlSet\Enum\" + DevType + "\\" + DeviceInstanceId + "\\" + DeviceUniqueID;
        RegistryKey key = Registry.LocalMachine.OpenSubKey(RegPath);
        if (key != null)
        {
            object result = key.GetValue("FriendlyName");
            if (result != null)
                return result.ToString();
            result = key.GetValue("DeviceDesc");
            if (result != null)
                return result.ToString();
        }
    }
    return String.Empty;
}
Run Code Online (Sandbox Code Playgroud)