我有两台扫描仪通过 USB 连接到我的机器(一台 EPSON 和一台 HP)。Windows 扫描和传真实用程序似乎确信这两台设备都是扫描仪,正如预期的那样。但是,当我查询系统上的 WIA 设备并在 C++ 程序中打印其属性时,HP 扫描仪被报告为“相机”类型。 EPSON 扫描仪被正确报告为扫描仪。
以下是两个设备的几个设备信息属性的输出:
Device ID: {6BDD1FC6-810F-11D0-BEC7-08002BE2092F}\0000
Vendor Description: EPSON
Device Description: EPSON DS-1630
Device Type: Scanner
Device Port Name: \\.\Usbscan1
Device Name: EPSON DS-1630
Device ID: {6BDD1FC6-810F-11D0-BEC7-08002BE2092F}\0001
Vendor Description: HP
Device Description: HP ENVY 5000 (USB)
Device Type: Camera
Device Port Name: \\.\Usbscan0
Device Name: HP ENVY 5000 (USB)
下面是我用来转储此信息的代码:
#include <Windows.h>
#include <stdio.h>
#include <wia.h>
int main(int argc, char **argv) {
argc;
argv;
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr)) {
fprintf(stderr, "CoInitializeEx failed\n");
goto cleanup;
}
IWiaDevMgr2 *dev_mgmt;
hr = CoCreateInstance(CLSID_WiaDevMgr2, NULL, CLSCTX_LOCAL_SERVER,
IID_IWiaDevMgr2, (void **)&dev_mgmt);
if (FAILED(hr)) {
fprintf(stderr, "CoCreateInstance failed\n");
goto cleanup;
}
IEnumWIA_DEV_INFO *dev_info = NULL;
hr = dev_mgmt->EnumDeviceInfo(WIA_DEVINFO_ENUM_LOCAL, &dev_info);
if (FAILED(hr)) {
fprintf(stderr, "EnumDeviceInfo Failed\n");
dev_mgmt->Release();
goto cleanup;
}
while (hr == S_OK) {
IWiaPropertyStorage *prop_storage = NULL;
hr = dev_info->Next(1, &prop_storage, NULL);
if (FAILED(hr)) {
break;
}
if (hr == S_OK) {
PROPSPEC prop_spec[6] = {0};
PROPVARIANT prop_var[6] = {0};
const ULONG prop_count = sizeof(prop_spec) / sizeof(prop_spec[0]);
// Device ID, VT_BSTR
prop_spec[0].ulKind = PRSPEC_PROPID;
prop_spec[0].propid = WIA_DIP_DEV_ID;
// Vendor Description, VT_BSTR
prop_spec[1].ulKind = PRSPEC_PROPID;
prop_spec[1].propid = WIA_DIP_VEND_DESC;
// Device Description, VT_BSTR
prop_spec[2].ulKind = PRSPEC_PROPID;
prop_spec[2].propid = WIA_DIP_DEV_DESC;
// Device Type, VT_I4
prop_spec[3].ulKind = PRSPEC_PROPID;
prop_spec[3].propid = WIA_DIP_DEV_TYPE;
// Device Port Name, VT_BSTR
prop_spec[4].ulKind = PRSPEC_PROPID;
prop_spec[4].propid = WIA_DIP_PORT_NAME;
// Device Name, VT_BSTR
prop_spec[5].ulKind = PRSPEC_PROPID;
prop_spec[5].propid = WIA_DIP_DEV_NAME;
hr = prop_storage->ReadMultiple(prop_count, prop_spec, prop_var);
if (FAILED(hr)) {
fprintf(stderr, "prop_storage->ReadMultiple failed");
break;
}
fprintf(stderr, "\nDevice ID: %S\n", prop_var[0].bstrVal);
fprintf(stderr, "Vendor Description: %S\n", prop_var[1].bstrVal);
fprintf(stderr, "Device Description: %S\n", prop_var[2].bstrVal);
if (prop_var[3].iVal == 0x0000) {
fprintf(stderr, "Device Type: Default\n");
} else if (prop_var[3].iVal == 0x0001) {
fprintf(stderr, "Device Type: Scanner\n");
} else if (prop_var[3].iVal == 0x0002) {
fprintf(stderr, "Device Type: Camera\n");
} else if (prop_var[3].iVal == 0x0003) {
fprintf(stderr, "Device Type: Video\n");
} else {
fprintf(stderr, "Device Type: Unknown (%d)\n", prop_var[3].iVal);
}
fprintf(stderr, "Device Port Name: %S\n", prop_var[4].bstrVal);
fprintf(stderr, "Device Name: %S\n", prop_var[5].bstrVal);
FreePropVariantArray(prop_count, prop_var);
prop_storage->Release();
prop_storage = NULL;
}
}
dev_info->Release();
dev_mgmt->Release();
cleanup:
CoUninitialize();
}
我忽略了一个事实,即我需要使用 GET_STIDEVICE_TYPE 宏来获取设备类型:
使用 GET_STIDEVICE_TYPE 宏获取设备类型。设备类型和子类型从 INF 文件中获取。应用程序读取此属性以确定它是否正在使用扫描仪、相机或视频设备。
在这种情况下,它们现在都是“默认”设备类型(但是不太确定这意味着什么)并且设备具有不同的子类型。这回答了我最初的问题,即为什么它显示为相机。
Device ID: {6BDD1FC6-810F-11D0-BEC7-08002BE2092F}\0000
Vendor Description: EPSON
Device Description: EPSON DS-1630
Device Type: Default (Type: 0x0000, SubType: 0x0001)
Device Port Name: \\.\Usbscan1
Device Name: EPSON DS-1630
Device ID: {6BDD1FC6-810F-11D0-BEC7-08002BE2092F}\0001
Vendor Description: HP
Device Description: HP ENVY 5000 (USB)
Device Type: Default (Type: 0x0000, SubType: 0x0002)
Device Port Name: \\.\Usbscan0
Device Name: HP ENVY 5000 (USB)
更新代码:
#include <Windows.h>
#include <stdio.h>
#include <sti.h>
#include <wia.h>
int main(int argc, char **argv) {
argc;
argv;
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr)) {
fprintf(stderr, "CoInitializeEx failed\n");
goto cleanup;
}
IWiaDevMgr2 *dev_mgmt;
hr = CoCreateInstance(CLSID_WiaDevMgr2, NULL, CLSCTX_LOCAL_SERVER,
IID_IWiaDevMgr2, (void **)&dev_mgmt);
if (FAILED(hr)) {
fprintf(stderr, "CoCreateInstance failed\n");
goto cleanup;
}
IEnumWIA_DEV_INFO *dev_info = NULL;
hr = dev_mgmt->EnumDeviceInfo(WIA_DEVINFO_ENUM_LOCAL, &dev_info);
if (FAILED(hr)) {
fprintf(stderr, "EnumDeviceInfo Failed\n");
dev_mgmt->Release();
goto cleanup;
}
while (hr == S_OK) {
IWiaPropertyStorage *prop_storage = NULL;
hr = dev_info->Next(1, &prop_storage, NULL);
if (FAILED(hr)) {
break;
}
if (hr == S_OK) {
PROPSPEC prop_spec[6] = {0};
PROPVARIANT prop_var[6] = {0};
const ULONG prop_count = sizeof(prop_spec) / sizeof(prop_spec[0]);
// Device ID, VT_BSTR
prop_spec[0].ulKind = PRSPEC_PROPID;
prop_spec[0].propid = WIA_DIP_DEV_ID;
// Vendor Description, VT_BSTR
prop_spec[1].ulKind = PRSPEC_PROPID;
prop_spec[1].propid = WIA_DIP_VEND_DESC;
// Device Description, VT_BSTR
prop_spec[2].ulKind = PRSPEC_PROPID;
prop_spec[2].propid = WIA_DIP_DEV_DESC;
// Device Type, VT_I4
prop_spec[3].ulKind = PRSPEC_PROPID;
prop_spec[3].propid = WIA_DIP_DEV_TYPE;
// Device Port Name, VT_BSTR
prop_spec[4].ulKind = PRSPEC_PROPID;
prop_spec[4].propid = WIA_DIP_PORT_NAME;
// Device Name, VT_BSTR
prop_spec[5].ulKind = PRSPEC_PROPID;
prop_spec[5].propid = WIA_DIP_DEV_NAME;
hr = prop_storage->ReadMultiple(prop_count, prop_spec, prop_var);
if (FAILED(hr)) {
fprintf(stderr, "prop_storage->ReadMultiple failed");
break;
}
fprintf(stderr, "\nDevice ID: %S\n", prop_var[0].bstrVal);
fprintf(stderr, "Vendor Description: %S\n", prop_var[1].bstrVal);
fprintf(stderr, "Device Description: %S\n", prop_var[2].bstrVal);
fprintf(stderr, "Device Type: ");
if (GET_STIDEVICE_TYPE(prop_var[3].iVal) == 0x0000) {
fprintf(stderr, "Default ");
} else if (GET_STIDEVICE_TYPE(prop_var[3].iVal) == 0x0001) {
fprintf(stderr, "Scanner ");
} else if (GET_STIDEVICE_TYPE(prop_var[3].iVal) == 0x0002) {
fprintf(stderr, "Camera ");
} else if (GET_STIDEVICE_TYPE(prop_var[3].iVal) == 0x0003) {
fprintf(stderr, "Video ");
} else {
fprintf(stderr, "Unknown ");
}
fprintf(stderr, "(Type: 0x%04X, SubType: 0x%04X)\n",
GET_STIDEVICE_TYPE(prop_var[3].iVal),
GET_STIDEVICE_SUBTYPE(prop_var[3].iVal));
fprintf(stderr, "Device Port Name: %S\n", prop_var[4].bstrVal);
fprintf(stderr, "Device Name: %S\n", prop_var[5].bstrVal);
FreePropVariantArray(prop_count, prop_var);
prop_storage->Release();
prop_storage = NULL;
}
}
dev_info->Release();
dev_mgmt->Release();
cleanup:
CoUninitialize();
}