如何检查扫描仪是否已插入(C#、. NET TWAIN)
我在应用程序中使用http://www.codeproject.com/KB/dotnet/twaindotnet.aspx?msg=1007385#xx1007385xx的.NET TWAIN代码。
当我尝试在未插入扫描仪的情况下扫描图像时,该应用程序将冻结。
如何使用TWAIN驱动程序检查设备是否已插入?
解决方案
我开始时使用的是与我们从CodeProject下载的源代码相同的源代码,但是将MainFrame.cs中的大多数代码移到了启动扫描程序的Scanner类上。为了检查扫描错误,我代替了Twain.Acquire直接调用以下方法:
enum AcquireResult { OK = 0, InitFailed = 1, DeviceIDFailed = 2, CapabilityFailed = 3, UserInterfaceError = 4 } private void StartScan() { if (!_msgFilter) { _parent.Enabled = false; _msgFilter = true; Application.AddMessageFilter(this); } AcquireResult ar = _twain.Acquire(); if (ar != AcquireResult.OK) { EndingScan(); switch (ar) { case AcquireResult.CapabilityFailed: throw new Exception("Scanner capability setup failed"); case AcquireResult.DeviceIDFailed: throw new Exception("Unable to determine device identity"); case AcquireResult.InitFailed: throw new Exception("Scanner initialisation failed"); case AcquireResult.UserInterfaceError: throw new Exception("Error with the Twain user interface"); default: throw new Exception("Document scanning failed"); } } }
我通常在单独的线程上启动扫描事件,以使应用程序在扫描过程中不会冻结。
也许我是从字面上讲这个问题,但是使用TWAIN API,无法检查设备是否已插入,即是否已连接并已打开电源。 TWAIN标准确实为此目的定义了一种称为CAP_DEVICEONLINE的功能,但是这个功能的构想太差了,几乎没有驱动程序正确地实现它,以至于在实践中没有用。
我们可以得到的最接近的信息是:打开设备(MSG_OPENDS):几乎所有驱动程序在打开时都会检查设备是否就绪,并向用户显示错误对话框。没有用于抑制或者检测该对话框的TWAIN机制。某些驱动程序将允许用户纠正问题并继续,在这种情况下,我们(应用程序)将永远不会知道有问题。一些驱动程序将允许用户取消,在这种情况下,MSG_OPENDS操作将失败,可能返回TWRC_CANCEL,但可能会返回TWRC_FAILURE
即使设备处于脱机状态,也会打开几个TWAIN驱动程序而不会出现错误。这样的驱动程序可以将FALSE返回到CAP_DEVICEONLINE的查询。当使用MSG_ENABLEDS启用设备时,这样的驱动程序可能会进行设备在线检查,然后,如果设备不是在线的,则会向用户显示错误对话框,依此类推。
除了IMPO:WIA比TWAIN更加"现代",但扫描的综合性却差很多,以我的经验,它不能用于从文档进纸器进行多页扫描。 WIA的设计人员和维护人员似乎不了解或者不在意低端家用平板扫描仪。这对相机很有好处。
只需在TwainCommand(cmd)上添加此代码
case TwainCommand.Null: { EndingScan(); tw.CloseSrc(); Msgbox("There is no device or the scannning has been cancelled."); break; }
如果系统未检测到设备或者扫描已取消,则将出现此消息。
我尝试执行此操作,但不能与TWAIN一起使用,请尝试WIA
我可以试试这个:
在buton上运行扫描仪
timer1.Interval = 30000; switch (cmd) { case TwainCommand.TransferReady: { .......... } default: { timer1.Start(); break; }
在事件计时器上打勾
{ EndingScan(); tw.CloseSrc(); }