Использование сканера без диалогов на C #

Я создаю приложение .Net 4.0 для удаленного управления устройством сканера. Я пробовал библиотеки TWAIN и WIA, но у меня та же проблема. Сканирование изображений без выбора сканера и диалоговых окон настроек сканирования.

Я нашел полезную статью о сценариях WIA в .Net и изменил ее на :

private Image Scan(string deviceName)
{
    WiaClass wiaManager = null;       // WIA manager COM object
    CollectionClass wiaDevs = null;   // WIA devices collection COM object
    ItemClass wiaRoot = null;         // WIA root device COM object
    CollectionClass wiaPics = null;   // WIA collection COM object
    ItemClass wiaItem = null;         // WIA image COM object

    try
    {
        // create COM instance of WIA manager
        wiaManager = new WiaClass();

        // call Wia.Devices to get all devices
        wiaDevs = wiaManager.Devices as CollectionClass;
        if ((wiaDevs == null) || (wiaDevs.Count == 0))
        {
            throw new Exception("No WIA devices found!");
        }

        object device = null;
        foreach (IWiaDeviceInfo currentDevice in wiaManager.Devices)
        {
            if (currentDevice.Name == deviceName)
            {
                device = currentDevice;
                break;
            }
        }

        if (device == null)
        {
            throw new Exception
            (
                "Device with name \"" + 
                deviceName + 
                "\" could not be found."
            );
        }

        // select device
        wiaRoot = (ItemClass)wiaManager.Create(ref device); 

        // something went wrong
        if (wiaRoot == null)
        {
            throw new Exception
            (
                "Could not initialize device \"" + 
                deviceName + "\"."
            );
        }

        wiaPics = wiaRoot.GetItemsFromUI
        (
            WiaFlag.SingleImage,
            WiaIntent.ImageTypeColor
        ) as CollectionClass;

        if (wiaPics == null || wiaPics.Count == 0)
        {
            throw new Exception("Could not scan image.");
        }

        Image image = null;

        // enumerate all the pictures the user selected
        foreach (object wiaObj in wiaPics)
        {
            if (image == null)
            {
                wiaItem = (ItemClass)Marshal.CreateWrapperOfType
                (
                    wiaObj, typeof(ItemClass)
                );

                // create temporary file for image
                string tempFile = Path.GetTempFileName();

                // transfer picture to our temporary file
                wiaItem.Transfer(tempFile, false);

                // create Image instance from file
                image = Image.FromFile(tempFile);
            }

            // release enumerated COM object
            Marshal.ReleaseComObject(wiaObj);
        }

        if (image == null)
        {
            throw new Exception("Error reading scanned image.");
        }

        return image;
    }
    finally
    {
        // release WIA image COM object
        if (wiaItem != null)
            Marshal.ReleaseComObject(wiaItem);

        // release WIA collection COM object
        if (wiaPics != null)
            Marshal.ReleaseComObject(wiaPics);

        // release WIA root device COM object
        if (wiaRoot != null)
            Marshal.ReleaseComObject(wiaRoot);

        // release WIA devices collection COM object
        if (wiaDevs != null)
            Marshal.ReleaseComObject(wiaDevs);

        // release WIA manager COM object
        if (wiaManager != null)
            Marshal.ReleaseComObject(wiaManager);
    }
}

Благодаря этому мне действительно удалось выбрать устройство из конфигурации (входной параметр метода сканирования) и получить полученное изображение после сканирования.

Но проблема с диалогом настроек сканирования (Scan using DEVICENAME). Поскольку это приложение для удаленного управления, диалоговое окно не будет отображаться для пользователя, поэтому мне нужно либо пропустить его, используя настройки по умолчанию, либо при необходимости использовать настройки из конфигурации.

Диалоговое окно параметров сканирования: диалоговое окно параметров сканирования


person Miljenko Barbir    schedule 25.03.2011    source источник
comment
Как вы думаете, возможно, если вы пытаетесь избежать появления какого-либо пользовательского интерфейса, вызов GetItemsFromUI может быть корнем вашей проблемы?   -  person Damien_The_Unbeliever    schedule 25.03.2011
comment
Между прочим, это делается с помощью библиотеки типов Microsoft Windows Image Acquisition 1.01, но любая другая библиотека приветствуется, если она решает эту проблему.   -  person Miljenko Barbir    schedule 25.03.2011
comment
@Damien_The_Unbeliever: LOL, это должно быть проблема, но какая альтернатива ...   -  person Miljenko Barbir    schedule 25.03.2011
comment
Разве вы не можете просто использовать wiaRoot.Children?   -  person Gabe    schedule 25.03.2011
comment
@Gabe: Что я могу сделать с wiaRoot.Children?   -  person Miljenko Barbir    schedule 25.03.2011


Ответы (3)


В итоге я не использовал код, указанный в вопросе, для сканирования диалогов. Я нашел полезный пример сканирования с помощью Windows Image Acquisition 2.0, который в этом способе также был диалог блокировки, но его легко изменить, и через несколько мгновений у меня был простой класс с функцией Scan(string scannerId), которая просто сканировала с помощью выбранного устройства и не более того, см. код () ниже:

using System;
using System.Collections.Generic;
using System.IO;
using System.Drawing;

namespace WIATest
{
    class WIAScanner
    {
        const string wiaFormatBMP = "{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}";

        class WIA_DPS_DOCUMENT_HANDLING_SELECT
        {
            public const uint FEEDER = 0x00000001;
            public const uint FLATBED = 0x00000002;
        }

        class WIA_DPS_DOCUMENT_HANDLING_STATUS
        {
            public const uint FEED_READY = 0x00000001;
        }

        class WIA_PROPERTIES
        {
            public const uint WIA_RESERVED_FOR_NEW_PROPS = 1024;
            public const uint WIA_DIP_FIRST = 2;
            public const uint WIA_DPA_FIRST = WIA_DIP_FIRST + WIA_RESERVED_FOR_NEW_PROPS;
            public const uint WIA_DPC_FIRST = WIA_DPA_FIRST + WIA_RESERVED_FOR_NEW_PROPS;
            //
            // Scanner only device properties (DPS)
            //
            public const uint WIA_DPS_FIRST = WIA_DPC_FIRST + WIA_RESERVED_FOR_NEW_PROPS;
            public const uint WIA_DPS_DOCUMENT_HANDLING_STATUS = WIA_DPS_FIRST + 13;
            public const uint WIA_DPS_DOCUMENT_HANDLING_SELECT = WIA_DPS_FIRST + 14;
        }

        /// <summary>
        /// Use scanner to scan an image (with user selecting the scanner from a dialog).
        /// </summary>
        /// <returns>Scanned images.</returns>
        public static List<Image> Scan()
        {
            WIA.ICommonDialog dialog = new WIA.CommonDialog();
            WIA.Device device = dialog.ShowSelectDevice(WIA.WiaDeviceType.UnspecifiedDeviceType, true, false);

            if (device != null)
            {
                return Scan(device.DeviceID);
            }
            else
            {
                throw new Exception("You must select a device for scanning.");
            }
        }

        /// <summary>
        /// Use scanner to scan an image (scanner is selected by its unique id).
        /// </summary>
        /// <param name="scannerName"></param>
        /// <returns>Scanned images.</returns>
        public static List<Image> Scan(string scannerId)
        {
            List<Image> images = new List<Image>();

            bool hasMorePages = true;
            while (hasMorePages)
            {
                // select the correct scanner using the provided scannerId parameter
                WIA.DeviceManager manager = new WIA.DeviceManager();
                WIA.Device device = null;

                foreach (WIA.DeviceInfo info in manager.DeviceInfos)
                {
                    if (info.DeviceID == scannerId)
                    {
                        // connect to scanner
                        device = info.Connect();
                        break;
                    }
                }

                // device was not found
                if (device == null)
                {
                    // enumerate available devices
                    string availableDevices = "";
                    foreach (WIA.DeviceInfo info in manager.DeviceInfos)
                    {
                        availableDevices += info.DeviceID + "n";
                    }

                    // show error with available devices
                    throw new Exception("The device with provided ID could not be found. Available Devices:n" + availableDevices);
                }

                WIA.Item item = device.Items[1] as WIA.Item;

                try
                {
                    // scan image
                    WIA.ICommonDialog wiaCommonDialog = new WIA.CommonDialog();
                    WIA.ImageFile image = (WIA.ImageFile)wiaCommonDialog.ShowTransfer(item, wiaFormatBMP, false);

                    // save to temp file
                    string fileName = Path.GetTempFileName();
                    File.Delete(fileName);
                    image.SaveFile(fileName);
                    image = null;

                    // add file to output list
                    images.Add(Image.FromFile(fileName));
                }
                catch (Exception exc)
                {
                    throw exc;
                }
                finally
                {
                    item = null;

                    //determine if there are any more pages waiting
                    WIA.Property documentHandlingSelect = null;
                    WIA.Property documentHandlingStatus = null;

                    foreach (WIA.Property prop in device.Properties)
                    {
                        if (prop.PropertyID == WIA_PROPERTIES.WIA_DPS_DOCUMENT_HANDLING_SELECT)
                            documentHandlingSelect = prop;

                        if (prop.PropertyID == WIA_PROPERTIES.WIA_DPS_DOCUMENT_HANDLING_STATUS)
                            documentHandlingStatus = prop;
                    }

                    // assume there are no more pages
                    hasMorePages = false;

                    // may not exist on flatbed scanner but required for feeder
                    if (documentHandlingSelect != null)
                    {
                        // check for document feeder
                        if ((Convert.ToUInt32(documentHandlingSelect.get_Value()) &amp;amp;amp;amp; WIA_DPS_DOCUMENT_HANDLING_SELECT.FEEDER) != 0)
                        {
                            hasMorePages = ((Convert.ToUInt32(documentHandlingStatus.get_Value()) &amp;amp;amp;amp; WIA_DPS_DOCUMENT_HANDLING_STATUS.FEED_READY) != 0);
                        }
                    }
                }
            }

            return images;
        }

        /// <summary>
        /// Gets the list of available WIA devices.
        /// </summary>
        /// <returns></returns>
        public static List<string> GetDevices()
        {
            List<string> devices = new List<string>();
            WIA.DeviceManager manager = new WIA.DeviceManager();

            foreach (WIA.DeviceInfo info in manager.DeviceInfos)
            {
                devices.Add(info.DeviceID);
            }

            return devices;
        }

    }
}
person Miljenko Barbir    schedule 26.03.2011

Во-первых, большое спасибо Miljenko Barbir за его решение, указанное выше, оно отлично работает.

Я хотел бы добавить, что если вам нужно ноль диалогов, вы можете использовать (из демонстрационного кода Милиженко)

WIA.ImageFile image = item.Transfer(wiaFormatBMP);

вместо

WIA.ImageFile image = (WIA.ImageFile)wiaCommonDialog.ShowTransfer(item, wiaFormatBMP, false);

По сути, это также удаляет индикатор выполнения, поэтому вы можете сканировать без каких-либо диалогов.

person Greg Netland    schedule 08.07.2014
comment
Это действительно помогло мне изменить код на adfwia.codeplex.com для сканирования без какого-либо пользовательского интерфейса. Большое спасибо. - person Vishnoo Rath; 03.12.2014
comment
@Greg, большое спасибо. это сэкономило мое время - person SaddamBinSyed; 12.10.2017

// show scanner view 
guif.ShowUI = 0;
guif.ModalUI = 0;

Вы можете увидеть в этом коде, который я реализовал.

person user2450942    schedule 04.06.2013