如何检查扫描仪是否已插入(C#,。NET TWAIN)

时间:2021-11-10 07:21:19

I'm using the .NET TWAIN code from http://www.codeproject.com/KB/dotnet/twaindotnet.aspx?msg=1007385#xx1007385xx in my application. When I try to scan an image when the scanner is not plugged in, the application freezes.

我在我的应用程序中使用http://www.codeproject.com/KB/dotnet/twaindotnet.aspx?msg=1007385#xx1007385xx中的.NET TWAIN代码。当我没有插入扫描仪时尝试扫描图像时,应用程序会冻结。

How can I check if the device is plugged in, using the TWAIN driver?

如何使用TWAIN驱动程序检查设备是否已插入?

5 个解决方案

#1


12  

Maybe I'm taking the question too literally, but using the TWAIN API, it is not possible to check if a device is plugged in i.e. connected and powered on. The TWAIN standard does define a capability for this purpose called CAP_DEVICEONLINE, but this feature is so poorly conceived and so few drivers implement it correctly that it is useless in practice.

也许我在字面上提出这个问题,但是使用TWAIN API,无法检查设备是否已插入,即连接和打开电源。 TWAIN标准确实为此目的定义了一个名为CAP_DEVICEONLINE的功能,但是这个功能设计得很差,很少有驱动程序正确实现它在实践中没用。

The closest you can get is this: Open the device (MSG_OPENDS): Almost all drivers will check for device-ready when they are opened, and will display an error dialog to the user. There is no TWAIN mechanism for suppressing or detecting this dialog Some drivers will allow the user to correct the problem and continue, in which case you (your app) will never know there was a problem. Some drivers will allow the user to cancel, in which case the MSG_OPENDS operation will fail, probably returning TWRC_CANCEL but maybe TWRC_FAILURE

最接近的是:打开设备(MSG_OPENDS):几乎所有驱动程序在打开时都会检查设备就绪,并向用户显示错误对话框。没有用于抑制或检测此对话框的TWAIN机制某些驱动程序将允许用户更正问题并继续,在这种情况下,您(您的应用程序)将永远不会知道存在问题。一些驱动程序将允许用户取消,在这种情况下MSG_OPENDS操作将失败,可能返回TWRC_CANCEL但可能是TWRC_FAILURE

A few TWAIN drivers will open without error even though the device is off-line. Such a driver may return FALSE to a query of CAP_DEVICEONLINE. Such a driver will probably do the device-online check when you enable the device with MSG_ENABLEDS, and then if the device is not on-line, you get the error dialog to the user, and so on as above.

即使设备处于脱机状态,一些TWAIN驱动程序也会毫无错误地打开。这样的驱动程序可能会返回FALSE到CAP_DEVICEONLINE的查询。当您使用MSG_ENABLEDS启用设备时,此类驱动程序可能会执行设备联机检查,然后如果设备未联机,则会向用户显示错误对话框,依此类推。

Aside and IMPO: WIA is 'more modern' but also much less comprehensive for scanning than TWAIN, and in my experience unusable for multipage scanning from a document feeder. WIA's designers and maintainers seem not to understand or care about scanners other than low-end consumer flatbeds. It's good for cameras.

除了和IMPO:WIA“更现代”,但扫描的全面性不如TWAIN,而且我的经验无法用于文档进纸器的多页扫描。 WIA的设计师和维护者似乎不了解或关心低端消费平板以外的扫描仪。这对相机很有用。

#2


2  

I started of with the same source code that you downloaded from CodeProject, but moved most of the code in MainFrame.cs that initiates the scanning to a Scanner class. In order to check for scan errors I call the following method in stead of calling Twain.Acquire directly:

我开始使用从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");
        }
    }
}

I usually initiate the scan event on a seperate thread in order for the app not to freeze while scanning is in progress.

我通常在单独的线程上启动扫描事件,以便在扫描过程中应用程序不会冻结。

#3


1  

just add this code on your TwainCommand (cmd)

只需在TwainCommand(cmd)上添加此代码

case TwainCommand.Null:
    {
     EndingScan();
     tw.CloseSrc();
             Msgbox("There is no device or the scannning has been cancelled.");
     break;
    }

this will appear if the systems detect no device or the scanning has been cancelled.

如果系统检测不到设备或扫描已取消,则会出现此信息。

#4


1  

You can check in the registry. In:

您可以登记注册表。在:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{6bdd1fc6-810f-11d0-bec7-08002be2092f} each scanner that's ever been detected is enumerated there in the subkeys.

HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Control \ Class \ {6bdd1fc6-810f-11d0-bec7-08002be2092f}每个检测到的扫描程序都在子项中枚举。

Starting with 0000, go through and check if the CreateFileName value is blank or has data.

从0000开始,检查CreateFileName值是空白还是有数据。

If it has data, it's a connected scanner, if it's blank, it's not connected.

如果它有数据,则它是连接的扫描仪,如果它是空白的,则它没有连接。

#5


-2  

i try do this but dont work good with TWAIN mybe try WIA

我尝试这样做但是不能用TWAIN mybe尝试WIA

mybe try this:

mybe尝试这个:

on buton run scanner

在buton运行扫描仪

timer1.Interval = 30000;

switch (cmd)
{
case TwainCommand.TransferReady:

{
..........
}

default:

{
timer1.Start();
break;
}

on event timer tick

在事件计时器滴答

{
EndingScan();
tw.CloseSrc();
}

#1


12  

Maybe I'm taking the question too literally, but using the TWAIN API, it is not possible to check if a device is plugged in i.e. connected and powered on. The TWAIN standard does define a capability for this purpose called CAP_DEVICEONLINE, but this feature is so poorly conceived and so few drivers implement it correctly that it is useless in practice.

也许我在字面上提出这个问题,但是使用TWAIN API,无法检查设备是否已插入,即连接和打开电源。 TWAIN标准确实为此目的定义了一个名为CAP_DEVICEONLINE的功能,但是这个功能设计得很差,很少有驱动程序正确实现它在实践中没用。

The closest you can get is this: Open the device (MSG_OPENDS): Almost all drivers will check for device-ready when they are opened, and will display an error dialog to the user. There is no TWAIN mechanism for suppressing or detecting this dialog Some drivers will allow the user to correct the problem and continue, in which case you (your app) will never know there was a problem. Some drivers will allow the user to cancel, in which case the MSG_OPENDS operation will fail, probably returning TWRC_CANCEL but maybe TWRC_FAILURE

最接近的是:打开设备(MSG_OPENDS):几乎所有驱动程序在打开时都会检查设备就绪,并向用户显示错误对话框。没有用于抑制或检测此对话框的TWAIN机制某些驱动程序将允许用户更正问题并继续,在这种情况下,您(您的应用程序)将永远不会知道存在问题。一些驱动程序将允许用户取消,在这种情况下MSG_OPENDS操作将失败,可能返回TWRC_CANCEL但可能是TWRC_FAILURE

A few TWAIN drivers will open without error even though the device is off-line. Such a driver may return FALSE to a query of CAP_DEVICEONLINE. Such a driver will probably do the device-online check when you enable the device with MSG_ENABLEDS, and then if the device is not on-line, you get the error dialog to the user, and so on as above.

即使设备处于脱机状态,一些TWAIN驱动程序也会毫无错误地打开。这样的驱动程序可能会返回FALSE到CAP_DEVICEONLINE的查询。当您使用MSG_ENABLEDS启用设备时,此类驱动程序可能会执行设备联机检查,然后如果设备未联机,则会向用户显示错误对话框,依此类推。

Aside and IMPO: WIA is 'more modern' but also much less comprehensive for scanning than TWAIN, and in my experience unusable for multipage scanning from a document feeder. WIA's designers and maintainers seem not to understand or care about scanners other than low-end consumer flatbeds. It's good for cameras.

除了和IMPO:WIA“更现代”,但扫描的全面性不如TWAIN,而且我的经验无法用于文档进纸器的多页扫描。 WIA的设计师和维护者似乎不了解或关心低端消费平板以外的扫描仪。这对相机很有用。

#2


2  

I started of with the same source code that you downloaded from CodeProject, but moved most of the code in MainFrame.cs that initiates the scanning to a Scanner class. In order to check for scan errors I call the following method in stead of calling Twain.Acquire directly:

我开始使用从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");
        }
    }
}

I usually initiate the scan event on a seperate thread in order for the app not to freeze while scanning is in progress.

我通常在单独的线程上启动扫描事件,以便在扫描过程中应用程序不会冻结。

#3


1  

just add this code on your TwainCommand (cmd)

只需在TwainCommand(cmd)上添加此代码

case TwainCommand.Null:
    {
     EndingScan();
     tw.CloseSrc();
             Msgbox("There is no device or the scannning has been cancelled.");
     break;
    }

this will appear if the systems detect no device or the scanning has been cancelled.

如果系统检测不到设备或扫描已取消,则会出现此信息。

#4


1  

You can check in the registry. In:

您可以登记注册表。在:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{6bdd1fc6-810f-11d0-bec7-08002be2092f} each scanner that's ever been detected is enumerated there in the subkeys.

HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Control \ Class \ {6bdd1fc6-810f-11d0-bec7-08002be2092f}每个检测到的扫描程序都在子项中枚举。

Starting with 0000, go through and check if the CreateFileName value is blank or has data.

从0000开始,检查CreateFileName值是空白还是有数据。

If it has data, it's a connected scanner, if it's blank, it's not connected.

如果它有数据,则它是连接的扫描仪,如果它是空白的,则它没有连接。

#5


-2  

i try do this but dont work good with TWAIN mybe try WIA

我尝试这样做但是不能用TWAIN mybe尝试WIA

mybe try this:

mybe尝试这个:

on buton run scanner

在buton运行扫描仪

timer1.Interval = 30000;

switch (cmd)
{
case TwainCommand.TransferReady:

{
..........
}

default:

{
timer1.Start();
break;
}

on event timer tick

在事件计时器滴答

{
EndingScan();
tw.CloseSrc();
}