Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从WM_DEVICECHANGE LParam获取设备的友好名称_C#_Winapi_Pinvoke - Fatal编程技术网

C# 从WM_DEVICECHANGE LParam获取设备的友好名称

C# 从WM_DEVICECHANGE LParam获取设备的友好名称,c#,winapi,pinvoke,C#,Winapi,Pinvoke,因此,我正在为一台学校电脑构建一个应用程序,它可以跟踪所有插入的设备。 无论何时插入或删除设备,我都设法使用RegisterDeviceNotification在主线程中获取通知。 不过,我只能得到LPRAM,一个设备唯一的指针 我找不到任何关于如何使用该LPRAM获取设备的友好名称的信息。 我能找到的唯一资源是C++中的2006的代码项目。 我在pinvoke.net上找不到任何东西,我发现的唯一一件事我记不清在哪里使用ManagementObjectSearcher来获取此数据,但它会找到空

因此,我正在为一台学校电脑构建一个应用程序,它可以跟踪所有插入的设备。 无论何时插入或删除设备,我都设法使用RegisterDeviceNotification在主线程中获取通知。 不过,我只能得到LPRAM,一个设备唯一的指针

我找不到任何关于如何使用该LPRAM获取设备的友好名称的信息。 我能找到的唯一资源是C++中的2006的代码项目。 我在pinvoke.net上找不到任何东西,我发现的唯一一件事我记不清在哪里使用ManagementObjectSearcher来获取此数据,但它会找到空数据。这是密码

ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select Name from Win32_PnpEntity");

            foreach (ManagementObject devices in searcher.Get())
            {
                foreach (var v in devices.Properties)
                {
                    Console.WriteLine(v.Value);
                }
            }

            searcher.Dispose();
有人能帮我弄清楚如何获得设备的友好名称吗

您需要向注册设备通知

因此,您将收到此消息

在这里,您需要检查wParam的和 事件

检查dbcc_devicetype==DBT_DEVTYP_DEVICEINTERFACE

你的内心 设备接口名称

您可以在内部使用此名称 带on的函数 事件

你有

在通话中使用它

在调用中使用result with 或

你只能看着自己 数据库,如果您在到达时为这样的名称和友好 名字

演示代码:

struct DeviceName : public LIST_ENTRY 
{
    ULONG InterfaceHash;
    WCHAR Name[];

    void* operator new(size_t cb, size_t len)
    {
        return LocalAlloc(0, cb + len);
    }

    void operator delete(void* pv)
    {
        LocalFree(pv);
    }
};

volatile const UCHAR guz = 0;
CONFIGRET GetFriendlyNameByDevNode(DeviceName** pp, DEVINST dnDevInst)
{
    CONFIGRET status;

    ULONG cb = 32;

    DEVPROPTYPE PropertyType;

    do 
    {
        if (DeviceName* p = new(cb) DeviceName)
        {
            status = CM_Get_DevNode_PropertyW(
                dnDevInst, &DEVPKEY_DeviceInterface_FriendlyName, &PropertyType, (PBYTE)p->Name, &cb, 0);

            if (status == CR_SUCCESS)
            {
                if (PropertyType == DEVPROP_TYPE_STRING)
                {
                    *pp = p;
                    return CR_SUCCESS;
                }
                else
                {
                    status = CR_WRONG_TYPE;
                }
            }

            delete p;
        }
        else
        {
            status = CR_OUT_OF_MEMORY;
        }

    } while (CR_BUFFER_SMALL == status);

    return status;
}

CONFIGRET GetFriendlyNameByInterface(DeviceName** pp, PCWSTR pszDeviceInterface)
{
    // RTCu must be disabled !
    ULONG cb = 0, rcb = 64;

    PVOID stack = alloca(guz);
    DEVPROPTYPE PropertyType;

    CONFIGRET status;

    union {
        PVOID pv;
        PWSTR DeviceID;
        PBYTE pb;
    };

    do 
    {
        if (cb < rcb)
        {
            rcb = cb = RtlPointerToOffset(pv = alloca(rcb - cb), stack);
        }

    } while (CR_BUFFER_SMALL == (status = CM_Get_Device_Interface_PropertyW(
        pszDeviceInterface, &DEVPKEY_Device_InstanceId, &PropertyType, pb, &rcb, 0)));

    if (status == CR_SUCCESS)
    {
        if (PropertyType == DEVPROP_TYPE_STRING)
        {
            DEVINST dnDevInst;

            status = CM_Locate_DevNodeW(&dnDevInst, DeviceID, CM_LOCATE_DEVNODE_NORMAL);

            return status == CR_SUCCESS ? GetFriendlyNameByDevNode(pp, dnDevInst) : status;
        }
        else
        {
            status = CR_WRONG_TYPE;
        }
    }

    return status;
}

        case WM_DESTROY:
            if (_hDevNot)
            {
                UnregisterDeviceNotification(_hDevNot);

                PLIST_ENTRY head = &_DevListHead, entry = head->Flink;

                while (entry != head)
                {
                    DeviceName* p = static_cast<DeviceName*>(entry);

                    entry = entry->Flink;

                    delete p;
                }
            }
            break;

        case WM_DEVICECHANGE:
            switch (wParam)
            {
            case DBT_DEVICEREMOVECOMPLETE:
            case DBT_DEVICEARRIVAL:
                if (reinterpret_cast<PDEV_BROADCAST_DEVICEINTERFACE>(lParam)->dbcc_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
                {
                    DeviceName* p;
                    ULONG InterfaceHash;
                    UNICODE_STRING dbcc_name;
                    RtlInitUnicodeString(&dbcc_name, reinterpret_cast<PDEV_BROADCAST_DEVICEINTERFACE>(lParam)->dbcc_name);
                    RtlHashUnicodeString(&dbcc_name, FALSE, HASH_STRING_ALGORITHM_DEFAULT, &InterfaceHash);

                    if (wParam == DBT_DEVICEARRIVAL)
                    {
                        if (CR_SUCCESS == GetFriendlyNameByInterface(&p, dbcc_name.Buffer))
                        {
                            p->InterfaceHash = InterfaceHash;
                            InsertHeadList(&_DevListHead, p);
                            DbgPrint("inserted %S ( %wZ )\n", p->Name, &dbcc_name);
                        }
                    }
                    else
                    {

                        PLIST_ENTRY head = &_DevListHead, entry = head;

                        while ((entry = entry->Flink) != head)
                        {
                            if (static_cast<DeviceName*>(entry)->InterfaceHash == InterfaceHash)
                            {
                                DbgPrint("removed %S ( %wZ )\n", 
                                    static_cast<DeviceName*>(entry)->Name, &dbcc_name);

                                RemoveEntryList(entry);
                                delete static_cast<DeviceName*>(entry);
                                break;
                            }
                        }
                    }
                }
                break;
            }
            return 0;

        case WM_CREATE:
            InitializeListHead(&_DevListHead);
            static DEV_BROADCAST_DEVICEINTERFACE dbd = { sizeof(dbd), DBT_DEVTYP_DEVICEINTERFACE };
            _hDevNot = RegisterDeviceNotificationW(hwnd, &dbd, DEVICE_NOTIFY_WINDOW_HANDLE|DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
            break;

当你说连接设备时,这主要是针对usbs的吗?以上代码对我适用。主要是针对USB设备,因为学生不太可能在学校随身携带thunderbolt 3图形卡或其他非USB设备,但我希望它能与所有设备一起工作。要阅读几乎所有有关检测到的USB设备的可用信息,当然,它不会只返回序列号。标记了.Net核心,但在.Net Framework中也是一样的。哪个答案?我联系的是后者?如果你是说那个,那是关于用于文件存储的USB设备。如果需要其他类型设备的信息,则必须查询其特定类别,例如Win32_Printer。如果您只需要一些基本信息,那么事件接口返回的信息可能就足以满足第一个链接中的要求。您还可以通过ID查询通用设备,以获取一些通用信息。这取决于你想走多深。此处实现的as不允许返回无效指针。@IInspectable-i overwrite operator new,如何查看。另外,我认为您知道5个变量,其中包含const std::nothrow\u t&tag,并在失败时返回空指针,而不是传播异常。。不管怎么说,我写的代码都有问题。那你想要什么?为什么你再提我使用工会的事?没什么可说的?当然,如果你愿意的话。您没有实现nothrow重载,因此是的,该实现返回无效指针是非法的。尽管这些都无关紧要,但由于避免使用适当的RAII包装器,您可能会左右泄漏资源。尽管如此,这一点也不重要,因为代码只是遵循您的标准,如果我无法观察到失败,那么代码就是正确的谬误。这里几乎没有任何有效的代码。我不会再解释了,因为你们不会理解。@IInspectable-具体代码中的资源泄漏在哪里?你能指出吗?我的新工作为什么?此代码编译时没有任何错误和警告。代码中的具体错误是什么?@IInspectable-潜在的资源泄漏并不意味着真实的。关于LocalAlloc适当对齐的内存-你错了。当我只需要sizeofULONG align时,此api返回2*sizeofpoid对齐内存。这里一切都好吗
struct DeviceName : public LIST_ENTRY 
{
    ULONG InterfaceHash;
    WCHAR Name[];

    void* operator new(size_t cb, size_t len)
    {
        return LocalAlloc(0, cb + len);
    }

    void operator delete(void* pv)
    {
        LocalFree(pv);
    }
};

volatile const UCHAR guz = 0;
CONFIGRET GetFriendlyNameByDevNode(DeviceName** pp, DEVINST dnDevInst)
{
    CONFIGRET status;

    ULONG cb = 32;

    DEVPROPTYPE PropertyType;

    do 
    {
        if (DeviceName* p = new(cb) DeviceName)
        {
            status = CM_Get_DevNode_PropertyW(
                dnDevInst, &DEVPKEY_DeviceInterface_FriendlyName, &PropertyType, (PBYTE)p->Name, &cb, 0);

            if (status == CR_SUCCESS)
            {
                if (PropertyType == DEVPROP_TYPE_STRING)
                {
                    *pp = p;
                    return CR_SUCCESS;
                }
                else
                {
                    status = CR_WRONG_TYPE;
                }
            }

            delete p;
        }
        else
        {
            status = CR_OUT_OF_MEMORY;
        }

    } while (CR_BUFFER_SMALL == status);

    return status;
}

CONFIGRET GetFriendlyNameByInterface(DeviceName** pp, PCWSTR pszDeviceInterface)
{
    // RTCu must be disabled !
    ULONG cb = 0, rcb = 64;

    PVOID stack = alloca(guz);
    DEVPROPTYPE PropertyType;

    CONFIGRET status;

    union {
        PVOID pv;
        PWSTR DeviceID;
        PBYTE pb;
    };

    do 
    {
        if (cb < rcb)
        {
            rcb = cb = RtlPointerToOffset(pv = alloca(rcb - cb), stack);
        }

    } while (CR_BUFFER_SMALL == (status = CM_Get_Device_Interface_PropertyW(
        pszDeviceInterface, &DEVPKEY_Device_InstanceId, &PropertyType, pb, &rcb, 0)));

    if (status == CR_SUCCESS)
    {
        if (PropertyType == DEVPROP_TYPE_STRING)
        {
            DEVINST dnDevInst;

            status = CM_Locate_DevNodeW(&dnDevInst, DeviceID, CM_LOCATE_DEVNODE_NORMAL);

            return status == CR_SUCCESS ? GetFriendlyNameByDevNode(pp, dnDevInst) : status;
        }
        else
        {
            status = CR_WRONG_TYPE;
        }
    }

    return status;
}

        case WM_DESTROY:
            if (_hDevNot)
            {
                UnregisterDeviceNotification(_hDevNot);

                PLIST_ENTRY head = &_DevListHead, entry = head->Flink;

                while (entry != head)
                {
                    DeviceName* p = static_cast<DeviceName*>(entry);

                    entry = entry->Flink;

                    delete p;
                }
            }
            break;

        case WM_DEVICECHANGE:
            switch (wParam)
            {
            case DBT_DEVICEREMOVECOMPLETE:
            case DBT_DEVICEARRIVAL:
                if (reinterpret_cast<PDEV_BROADCAST_DEVICEINTERFACE>(lParam)->dbcc_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
                {
                    DeviceName* p;
                    ULONG InterfaceHash;
                    UNICODE_STRING dbcc_name;
                    RtlInitUnicodeString(&dbcc_name, reinterpret_cast<PDEV_BROADCAST_DEVICEINTERFACE>(lParam)->dbcc_name);
                    RtlHashUnicodeString(&dbcc_name, FALSE, HASH_STRING_ALGORITHM_DEFAULT, &InterfaceHash);

                    if (wParam == DBT_DEVICEARRIVAL)
                    {
                        if (CR_SUCCESS == GetFriendlyNameByInterface(&p, dbcc_name.Buffer))
                        {
                            p->InterfaceHash = InterfaceHash;
                            InsertHeadList(&_DevListHead, p);
                            DbgPrint("inserted %S ( %wZ )\n", p->Name, &dbcc_name);
                        }
                    }
                    else
                    {

                        PLIST_ENTRY head = &_DevListHead, entry = head;

                        while ((entry = entry->Flink) != head)
                        {
                            if (static_cast<DeviceName*>(entry)->InterfaceHash == InterfaceHash)
                            {
                                DbgPrint("removed %S ( %wZ )\n", 
                                    static_cast<DeviceName*>(entry)->Name, &dbcc_name);

                                RemoveEntryList(entry);
                                delete static_cast<DeviceName*>(entry);
                                break;
                            }
                        }
                    }
                }
                break;
            }
            return 0;

        case WM_CREATE:
            InitializeListHead(&_DevListHead);
            static DEV_BROADCAST_DEVICEINTERFACE dbd = { sizeof(dbd), DBT_DEVTYP_DEVICEINTERFACE };
            _hDevNot = RegisterDeviceNotificationW(hwnd, &dbd, DEVICE_NOTIFY_WINDOW_HANDLE|DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
            break;