问题标签 [setupapi]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
167 浏览

c++ - windows:在蓝牙 api 和 setupapi 上检测相同的设备

我目前正在创建一个程序,该程序分为两部分,一个是我检测附近的蓝牙设备,如果名称匹配,将它们连接到电脑,另一个是我使用 setupapi 搜索设备并获取 HID 通信句柄。
我的问题是我找不到任何东西告诉我我刚刚连接的设备与我在 setupapi 中找到的设备相同。
所以在第一部分我有这样的事情:

以及setupapi相关代码:

我正在考虑使用设备的蓝牙地址,但似乎没有办法从 setupapi 获取。
那么,回顾一下,有没有办法从 setupi 获取设备的地址?如果没有,还有其他方法可以确保它们都是同一个设备吗?

0 投票
1 回答
173 浏览

windows - 如何通过 Setup API 获得一致的 deive 列表?

之前的一句话:大部分文本和代码如下,但我尝试尽可能详细地解释我的问题(随机发生):

我的应用程序通过 Setup API 处理网络接口,随机失败,很可能是在尝试使用SetupDiGetDeviceRegistryProperty()时。我遇到的主要问题是SetupDiEnumDeviceInfo()返回的设备列表(我使用它来获取将传递给SetupDiGetDeviceRegistryProperty()的特定网络适配器的索引)以“意外”方式改变。我的第一个问题是设备从该列表中出现和/或消失。如此处所述,我首先发现使用

代替

总是返回可以在设备管理器中看到的所有网络适配器(包括“隐藏”=“未安装”的)。到目前为止,这符合预期 - 使用 Windows 10(64 位)。

在很高兴它工作后,我编译了该应用程序以用于 Windows 7 32 位并对其进行测试。不幸的是,我必须看到仍然存在问题 - SetupDiEnumDeviceInfo() 仍按预期返回所有网络适配器,但顺序完全不同,并且 (a) 如果SetupDiGetDeviceRegistryProperty()因ERROR_INVALID_DATA失败而发生后续调用。大多数时候我得到

但有时顺序会这样改变:

使用下面的(Qt)代码可能会导致我确定的索引不再匹配预期的设备。有没有办法防止设备列表的顺序改变,或者我做错了什么?

被使用:

被使用:

0 投票
0 回答
169 浏览

c# - 在 Marshal.GetLastWin32Error() 上设置断点似乎是在修改最后一个错误集?

我在 Win10 x64 1809 上的 VS2019 中使用 C# 和 .NET 4.6。

使用 P/Invoke 时,在“Marshal.GetLastWin32Error()”行上设置断点似乎是在修改最后设置的 Win32 错误代码。

例如:

如果我在“return”上设置断点,重复运行将 endError 显示为 500。

但是,如果我在“int endError = Marshal.GetLastWin32Error();”上设置断点,重复运行会将 endError 显示为 0。


似乎在任何“Marshal.GetLastWin32Error()”行上设置断点都会产生意想不到的结果,就像在另一个区域中 P/Invoking SetupEnumInfSections() 我预期的 259 (ERROR_NO_MORE_ITEMS),但在设置断点后,收到 1008。


  • 我是否遗漏了在我的项目中导致这种行为的某些东西?(我从 CodeProject 和 GitHub 尝试了不同的项目,包括个人项目和第三方项目,并继续体验这种行为)
  • 这是 Visual Studio 中的错误(我应该报告这个吗?)
  • 这是预期的吗?(见下文)

我知道调用 Marshal.GetLastWin32Error() 需要在相关 API 调用之后立即调用(假设 API 调用确实设置了最后一个错误,并且对于 P/Invoke 调用,在它的装饰器中包含“SetLastError = true” ),因为任何额外的调用都可能修改最后一个错误的值。

但是,在调试、在 Marshal.GetLastWin32Error() 上设置断点等方面,我没有发现任何其他类型的警告。

这是使用 VS 编写 P/Invoke 的开发人员应该注意的“陷阱”,类似于立即使用 GetLastError() 进行 API 调用并设置装饰器(“SetLastError = true”)?这可能是一个“陷阱”,但如果是这样,这对我来说并不是很明显,因为我希望每个进程都有自己的最后一个错误,包括 VS(和/或调试器),但它可能与底层应用程序有关以某种我不知道的方式。

0 投票
0 回答
320 浏览

c# - 如何从串口连接到蓝牙设备并取消配对

我正在使用 WMI 查询通过蓝牙连接的串行端口,我得到具有以下属性的管理对象:

我想做的是找到对应的蓝牙设备并以编程方式(C#或C++)取消配对。到目前为止,我还没有找到任何方法来做到这一点。卸载端口不会自动取消配对设备。

我试图将这些属性映射到 BT 设备驱动程序的属性,但没有找到匹配项...

0 投票
1 回答
360 浏览

c# - 在没有 libusb 的情况下在 C# 中获取 USB 设备描述符?

我想读取 USB 串行端口的设备描述符(不仅仅是 VID/PID——主要是这样我可以获得 bcdDevice、iProduct 和 iManufacturer),这样我就可以知道 USB 串行端口是否能够满足我的需求要做(我们在现场有几个调制解调器,其中一个在半双工时更可靠)。

我不想使用 libusbdotnet,因为我不希望我的用户必须提前弄清楚要过滤什么才能获得我感兴趣的端口。

我知道如何用 C 来做到这一点;查看 USBView 应用程序,我们将需要使用 SetupAPI 来枚举控制器 (SetupDiEnumDeviceInfo),然后是集线器,然后使用 IOCTL 查询集线器以获取每个端口上的内容。

我想我必须这样做,因为我无法从 COM13 找出映射 -> \.\USB#ROOT_HUB30#4&2a9d917a&0&0#{f18a0e88-c30c-11d0-8815-00a0c906bed8}..有没有更好/更简单的获取ioctl所需的文件名的方法,而不是全部通过并过滤它们?

我还尝试将 usbview 应用程序制作成 C DLL 并尝试围绕它制作一个包装器,但我无法让我自己开发的 DLL 正确编译...

我尝试将其从 usbview 添加到enum.c作为起点

但是我无法将生成的 DLL 加载到我的 C# 项目中(它在运行时崩溃 - 甚至在窗口出现之前)。查看 DLL,它似乎是垃圾(遍历 DLL 会导致 walker 崩溃)。所以......我不确定我在那里做错了什么,所以我打算将 enum.c 翻译成 C# pinvoke 风格并继续使用它,但这似乎需要做很多工作,特别是如果有一个获取 COM14 的更简单方法 -> \.\USB#ROOT_HUB30#4&2a9d917a&0&0#{f18a0e88-c30c-11d0-8815-00a0c906bed8} [Port1] 链接...

所以...我前面有很多工作要做,还是有更简单的方法来获取链接(我已经从注册表尝试过,但它似乎没有映射)。

0 投票
0 回答
234 浏览

driver - DiUninstallDriver 返回错误 NeedReboot

我正在使用DiUninstallDriver卸载驱动程序。

语法是:

NeedRebbot参数说明:

但在我的情况下,返回值为False(不需要重新启动),但在 setupapi.dev.log 中我看到需要重新启动

我对所需的重新启动没问题(可能打开了此驱动程序的句柄),为什么 API 返回 false 并且我没有指示需要重新启动?

0 投票
1 回答
1235 浏览

c++ - 使用 SetupAPI 获取有关设备的信息

我有一台通过 USB 端口连接的打印机,我想获得一些有关它的信息。我正在使用SetupDiEnumDeviceInfo函数 fromsetupapi来获取信息。我正在按照 MSDN 中的描述做所有事情。

问题是我总是得到false结果。 GetLastError()函数返回 259. 我做错了什么?

0 投票
2 回答
1158 浏览

windows - 如何使用设备实例 ID 打开设备句柄?

我正在更新我的问题,以更好地反映我实际追求的目标。为了快速说明我最初的困惑,说“设备接口类 GUID ”和设备实例 ID之间存在一对一的关系是不正确的。一个设备可以有很多设备接口。正如Ben Voigt在评论中指出的那样,有关更多信息,请参阅此内容。


CM_Get_Child (...)调用函数后如何打开子设备的句柄?

以下面的代码片段为例:

如何使用新获得的子设备实例 ID来打开设备的句柄? CreateFile (...)需要完整的设备路径,其中包括缺少的“设备接口类 GUID”。

更具体地说,设备路径具有以下格式:
\\?\usb#vid_2109&pid_0813#7&3981C8D6&0&2#{[DEVICE_INTERFACE_GUID]},其中:

  1. [DEVICE_INTERFACE_GUID] - 这是“设备接口类 GUID ”。这与“设备设置类 GUID 不同。

如果没有某种程度的蛮力(例如使用 CM_ENUMERATE_CLASSES_INTERFACE 标志),似乎没有一种简单的方法来获得这个“设备接口类 GUID ”。是否可以调用一个函数来仅使用设备的“设备实例 ID ”来获取设备的句柄,以便我可以调用和查询有关设备的信息?CM_Enumerate_Classes (...)DeviceIoControl (...)

0 投票
0 回答
248 浏览

windows - 如何获取与 PNPDeviceID ("SWD\MyEnumerator\MyInstance") 对应的 DeviceName ("\\.\DISPLAY1")?

为了管理显示适配器和显示属性,我的代码使用了来自两个不同 Windows DLL 的 API:

cfgMgr32.dll

我使用 CfgMgr32(SetupApi 的继承者)中的函数来:

  • 枚举适配器(获取 id 和属性)
  • 确定是否存在特定的适配器
  • 确定适配器是否启用/禁用
  • 启用/禁用适配器
  • 注册回调以接收 PnP 设备事件

CfgMgr32(和 SetupApi)中的 API 使用以下形式的适配器 ID(称为DeviceInstanceIdPNPDeviceID):"SWD\MyEnumerator\MyInstance"

User32.dll

我使用 User32 中的函数来:

  • 枚举适配器(获取 id 和属性)
  • 查询适配器支持的分辨率
  • 查询适配器当前的显示模式
  • 更改适配器的当前方向
  • 更改适配器的当前分辨率

User32 中的 API 使用完全不同的适配器 id(称为DeviceName)的形式:"\\.\DISPLAY23"

(惊人的)问题:

似乎没有记录在这两种形式的唯一标识符之间的映射方式。我可以启用一个适配器,但是当我想更改它的方向或分辨率时,我无法知道返回的哪些标识符是EnumDisplayDevices(...)指我刚刚启用的同一个适配器。

我需要的 API 分布在两个库中;这两个库都没有提供一整套显示适配器管理功能。

这两个库都具有让您获取有关特定适配器的信息的功能,并且有一些小的重叠,但至关重要的是:没有什么是单个适配器所独有的。也许有一些方法可以明确地将属性从一侧关联到另一侧,但我已经丢弃了所有可用的信息(包括 SystemInformation、Screen.AllScreens、Wmi 查询,如 Win32_VideoController、DISPLAY_DEVICE ......)以及所有我能做到的信息找不到任何可映射的东西。

有没有人解决过这个问题,或者知道一些可能值得一看的开源项目?

0 投票
1 回答
29 浏览

winapi - 为什么在 Windows SetupAPI 中 LogSeverity #defined 为 DWORD

我在第 4871 行的 windows kit 10 SetupAPI.h 中看到了这个 #define

#define LogSeverity DWORD

所以我不能做类似的事情

typedef int 日志严重性

如果我不想重新定义 DWORD,这有效地使 LogSeverity 成为保留关键字。我在这里错过了什么吗?