为什么我的一台扫描仪在使用 Windows 图像采集 (WIA) 查询时显示为相机?

问题描述 投票:0回答:1

我有两台扫描仪通过 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)

windows scanner and fax util

下面是我用来转储此信息的代码:

#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();
}

c++ windows scanning wia
1个回答
0
投票

我忽略了一个事实,即我需要使用 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();
}

© www.soinside.com 2019 - 2024. All rights reserved.