WIA,无法枚举本机系统中的扫描仪

马少华 2017-03-29 05:03:38
先上代码,几乎是抄的msdn上的。
HRESULT CreateWiaDeviceManager(IWiaDevMgr2 **ppWiaDevMgr) //Vista or later
{
//
// Validate arguments
//
if (NULL == ppWiaDevMgr)
{
return E_INVALIDARG;
}

//
// Initialize out variables
//
*ppWiaDevMgr = NULL;

//
// Create an instance of the device manager
//

//XP or earlier:
//HRESULT hr = CoCreateInstance(CLSID_WiaDevMgr, NULL, CLSCTX_LOCAL_SERVER, IID_IWiaDevMgr, (void**)ppWiaDevMgr);

//Vista or later:
HRESULT hr = CoCreateInstance(CLSID_WiaDevMgr2, NULL, CLSCTX_LOCAL_SERVER, IID_IWiaDevMgr2, (void**)ppWiaDevMgr);

//
// Return the result of creating the device manager
//
return hr;
}

HRESULT EnumerateWiaDevices(IWiaDevMgr2 *pWiaDevMgr) //Vista or later
{
//
// Validate arguments
//
if (NULL == pWiaDevMgr)
{
return E_INVALIDARG;
}

//
// Get a device enumerator interface
//
IEnumWIA_DEV_INFO *pWiaEnumDevInfo = NULL;
HRESULT hr = pWiaDevMgr->EnumDeviceInfo(WIA_DEVINFO_ENUM_LOCAL, &pWiaEnumDevInfo);
if (SUCCEEDED(hr))
{
//
// Loop until you get an error or pWiaEnumDevInfo->Next returns
// S_FALSE to signal the end of the list.
//
while (S_OK == hr)
{

u_long dicount = 0;
hr = pWiaEnumDevInfo->GetCount(&dicount);
//此处hr返回s_ok,但dicount为0,但我电脑上确实连接了一个扫描仪,驱动也装好了,可以正常使用
//
// Get the next device's property storage interface pointer
//
IWiaPropertyStorage *pWiaPropertyStorage = NULL;
hr = pWiaEnumDevInfo->Next(1, &pWiaPropertyStorage, NULL);
//这里直接返回S_FAILED
//
// pWiaEnumDevInfo->Next will return S_FALSE when the list is
// exhausted, so check for S_OK before using the returned
// value.
//
if (hr == S_OK)
{
//
// Do something with the device's IWiaPropertyStorage*
//

PROPSPEC PropSpec[3] = { 0 };
PROPVARIANT PropVar[3] = { 0 };

const u_long propcount = sizeof(PROPSPEC) / sizeof(PropSpec[0]);

//
// Define which properties you want to read:
// Device ID. This is what you would use to create
// the device.
//
PropSpec[0].ulKind = PRSPEC_PROPID;
PropSpec[0].propid = WIA_DIP_DEV_ID;

//
// Device Name
//
PropSpec[1].ulKind = PRSPEC_PROPID;
PropSpec[1].propid = WIA_DIP_DEV_NAME;

//
// Device description
//
PropSpec[2].ulKind = PRSPEC_PROPID;
PropSpec[2].propid = WIA_DIP_DEV_DESC;


hr = pWiaPropertyStorage->ReadMultiple(propcount, PropSpec, PropVar);
if (SUCCEEDED(hr))
{
//
// IWiaPropertyStorage::ReadMultiple will return S_FALSE if some
// properties could not be read, so you have to check the return
// types for each requested item.
//

//
// Check the return type for the device ID
//
if (VT_BSTR == PropVar[0].vt)
{
//
// Do something with the device ID
//
_tprintf(TEXT("WIA_DIP_DEV_ID: %ws\n"), PropVar[0].bstrVal);
}

//
// Check the return type for the device name
//
if (VT_BSTR == PropVar[1].vt)
{
//
// Do something with the device name
//
_tprintf(TEXT("WIA_DIP_DEV_NAME: %ws\n"), PropVar[1].bstrVal);
}

//
// Check the return type for the device description
//
if (VT_BSTR == PropVar[2].vt)
{
//
// Do something with the device description
//
_tprintf(TEXT("WIA_DIP_DEV_DESC: %ws\n"), PropVar[2].bstrVal);
}

//
// Free the returned PROPVARIANTs
//
FreePropVariantArray(propcount, PropVar);

}

//
// Release the device's IWiaPropertyStorage*
//
pWiaPropertyStorage->Release();
pWiaPropertyStorage = NULL;
}
}

//
// If the result of the enumeration is S_FALSE (which
// is normal), change it to S_OK.
//
if (S_FALSE == hr)
{
hr = S_OK;
}

//
// Release the enumerator
//
pWiaEnumDevInfo->Release();
pWiaEnumDevInfo = NULL;
}

//
// Return the result of the enumeration
//
return hr;
}




int main()
{
CoInitialize(NULL);
IWiaDevMgr2 *pWait;
HRESULT hr = CreateWiaDeviceManager(&pWait);
if (hr != S_OK)
{
_tprintf(_T("create devicemanager error %d"), GetLastError());
CoUninitialize();
return -1;
}

EnumerateWiaDevices(pWait);
getchar();
pWait->Release();
CoUninitialize();
return 0;
}


请用过wia的大牛指点一二。
...全文
356 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
马少华 2017-04-17
  • 打赏
  • 举报
回复
@bdmh @CharlesSimonyi @happyparrot 贴子给不了分,结不了贴,说所给分数与总分不符。一楼35,二楼5分,这个没算错吧。
赵4老师 2017-04-01
  • 打赏
  • 举报
回复
搜“devcon”?
马少华 2017-04-01
  • 打赏
  • 举报
回复
引用 1 楼 dream238 的回复:
WIA_DEVINFO_ENUM_LOCAL改成WIA_DEVINFO_ENUM_ALL试试 先把所有能找到的设备找出来,然后再过滤掉非活动的设备试试。
这样确实可以枚举出两个设备。 但都只有guid,并没有设备名称,不知道为什么?
马少华 2017-04-01
  • 打赏
  • 举报
回复
又给不了分,结不了账,呼叫版主。提示给分与总分不符。但我确实没给错分。。。。
马少华 2017-04-01
  • 打赏
  • 举报
回复
引用 4 楼 dream238 的回复:
[quote=引用 2 楼 evionmzs 的回复:] 这样确实可以枚举出两个设备。 但都只有guid,并没有设备名称,不知道为什么?
你可以多列一些属性出来,看看找到的设备对不对,具体的属性参数参考MSDN:https://msdn.microsoft.com/en-us/library/windows/desktop/ms630186(v=vs.85).aspx 取的时候注意属性类型是数字还是字符串,可以尽可能的先试着把支持的属性列出来进行设备比对,因为设备名字除了那个DisplayName以外,设备的描述Desc也有可能会包含这一类的信息。 其实如果不考虑XP系统的话,Vista以上的环境可以考虑用WPD来访问这些设备:https://msdn.microsoft.com/en-us/library/windows/desktop/dd388998(v=vs.85).aspx P.S:太久没搞有点忘了怎么写了...不过当时,我资料都是从MSDN上参考来的,有啥不懂的多看API文档和示例吧。[/quote] 谢谢了,已经找到原因,设备还得安装针对WIA的驱动,才可以进行wia相关操作。准备改用TWAIN了。
ArcRain 2017-04-01
  • 打赏
  • 举报
回复
引用 2 楼 evionmzs 的回复:
这样确实可以枚举出两个设备。
但都只有guid,并没有设备名称,不知道为什么?


你可以多列一些属性出来,看看找到的设备对不对,具体的属性参数参考MSDN:https://msdn.microsoft.com/en-us/library/windows/desktop/ms630186(v=vs.85).aspx
取的时候注意属性类型是数字还是字符串,可以尽可能的先试着把支持的属性列出来进行设备比对,因为设备名字除了那个DisplayName以外,设备的描述Desc也有可能会包含这一类的信息。

其实如果不考虑XP系统的话,Vista以上的环境可以考虑用WPD来访问这些设备:https://msdn.microsoft.com/en-us/library/windows/desktop/dd388998(v=vs.85).aspx

P.S:太久没搞有点忘了怎么写了...不过当时,我资料都是从MSDN上参考来的,有啥不懂的多看API文档和示例吧。
ArcRain 2017-03-29
  • 打赏
  • 举报
回复
WIA_DEVINFO_ENUM_LOCAL改成WIA_DEVINFO_ENUM_ALL试试 先把所有能找到的设备找出来,然后再过滤掉非活动的设备试试。

2,640

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧