Как проверить, подключен ли сканер (C#, .NET TWAIN)
Вопрос
Я использую код .NET TWAIN из http://www.codeproject.com/KB/dotnet/twaindotnet.aspx?msg=1007385#xx1007385xx в моем приложении.Когда я пытаюсь отсканировать изображение, когда сканер не подключен, приложение зависает.
Как проверить, подключено ли устройство, с помощью драйвера TWAIN?
Решение
Возможно, я слишком буквально понимаю вопрос, но с помощью TWAIN API невозможно проверить, подключено ли устройство, т.е.подключен и включен.Стандарт TWAIN определяет для этой цели возможность под названием CAP_DEVICEONLINE, но эта функция настолько плохо продумана и так мало драйверов реализуют ее правильно, что на практике она бесполезна.
Самое близкое, что вы можете получить, это:Откройте устройство (MSG_OPENDS):Почти все драйверы проверяют готовность устройства при открытии и отображают пользователю диалоговое окно с ошибкой. Не существует механизма TWAIN для подавления или обнаружения этого диалогового окна. Некоторые драйверы позволяют пользователю исправить проблему и продолжить работу, и в этом случае вы (ваше приложение) никогда не узнаете о наличии проблемы.Некоторые драйверы позволяют пользователю отменить операцию, и в этом случае операция MSG_OPENDS завершится неудачей, возможно, вернув TWRC_CANCEL, но, возможно, TWRC_FAILURE.
Некоторые драйверы TWAIN откроются без ошибок, даже если устройство находится в автономном режиме.Такой водитель может верните FALSE в запрос CAP_DEVICEONLINE.Такой драйвер, вероятно, выполнит проверку подключения устройства к сети, когда вы включите устройство с помощью MSG_ENABLEDS, а затем, если устройство не подключено к сети, вы получите диалоговое окно ошибки для пользователя и так далее, как указано выше.
В сторону и ИМПО:WIA «более современен», но при этом гораздо менее универсален для сканирования, чем TWAIN, и, по моему опыту, его невозможно использовать для многостраничного сканирования из устройства подачи документов.Разработчики и специалисты WIA, похоже, не понимают и не интересуются сканерами, кроме недорогих потребительских планшетов.Это хорошо для камер.
Другие советы
Я начал с того же исходного кода, который вы скачали с 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");
}
}
}
Обычно я инициирую событие сканирования в отдельном потоке, чтобы приложение не зависало во время сканирования.
просто добавьте этот код в свой TwainCommand (cmd)
case TwainCommand.Null:
{
EndingScan();
tw.CloseSrc();
Msgbox("There is no device or the scannning has been cancelled.");
break;
}
это появится, если системы не обнаружили ни одного устройства или сканирование было отменено.
Вы можете проверить в реестре.В:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{6bdd1fc6-810f-11d0-bec7-08002be2092f}
каждый когда-либо обнаруженный сканер перечисляется в подразделах.
Начиная с 0000
, пройдите и проверьте, CreateFileName
значение пусто или содержит данные.
Если есть данные, значит сканер подключен, если пусто, значит не подключен.
я пытаюсь сделать это, но с TWAIN не получается, возможно, попробую WIA
возможно, попробую это:
по кнопке запуска сканера
timer1.Interval = 30000;
switch (cmd)
{
case TwainCommand.TransferReady:
{
..........
}
default:
{
timer1.Start();
break;
}
по таймеру события
{
EndingScan();
tw.CloseSrc();
}