简体   繁体   中英

C# Windows Image Acquisition Scan Throws Error at random scan interval

Currently I have an application where the user searches for an customer.

The problem starts here: The issue is happening at 3 work station at random intervals. The user(s) will search for a customer, then scan a paper via flatbed scanner ( epson perfection v600) then this information is saved. A user will repeat this process an X amount of time, but at a random amount, the application will throw the following error:

INNEREXCEPTION ERROR: Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED)) Exception Message: System call failed. (Exception from HRESULT: 0x80010100 (RPC_E_SYS_CALL_FAILED)) at WIA.ICommonDialog.ShowTransfer(Item Item, String FormatID, Boolean CancelError) at Radex.DocumentScanner.ScannerService.Scan(String scannerId, Boolean useFlatBedScanner, String batchNumber, Int32 batchCount) in C:\Projects\Framework.NET\Application\Framework\WPF\MyScanApp.DocumentScanner\ScannerService.cs:line 201

If we go to line 201, in ScannerService.cs.. this is the line of code that is throwing the error:

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

Has anyone encountered this error and or knows how to solve it? Below follows my button code that calls the scanning service to start the scanning procedure. Any feedback is highly appreciated since this issue is driving me crazy

Scanning Button:

 private void Scan()
        {
                List<BitmapSource> images = ScannerService.Scan((string)lbDevices.SelectedItem, true);

                if (images.Count > 0)
                {
                    foreach (var image in images)
                    {
                        AddScannedImage(GetJPGFromImageControl(image));
                    }
                    HasScannedDocument = "Visible";
                }
        }

AND here follows ScannerService class

  public class ScannerException : ApplicationException
    {
        public ScannerException()
            : base()
        { }

        public ScannerException(string message)
            : base(message)
        { }

        public ScannerException(string message, Exception innerException)
            : base(message, innerException)
        { }

    }

    public class ScannerNotFoundException : ScannerException
    {
        public ScannerNotFoundException()
            : base("Error retrieving a list of scanners. Is your scanner or multi-function printer turned on?")
        {
        }
    }

    public class EmptyFeedException : ScannerException
    {
        public EmptyFeedException()
            : base("Scanner Feed is empty")
        {
        }
    }


    public class ScannerService
    {
        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<BitmapSource> 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>
        /// 


        private static List<BitmapSource> bitmapSources;
        public static List<BitmapSource> BitmapSources
        {
            get { return bitmapSources; }
            set
            {
                if (bitmapSources != value)
                {
                    bitmapSources = value;
                }
            }
        }

        public static List<BitmapSource> Scan(string scannerId, bool useFlatBedScanner = false, string batchNumber = "", int batchCount = 0)
        {
            //   List<ImageFile> images = new List<ImageFile>();
            BitmapSources = new List<BitmapSource>();
            int count = 1;

            if (batchCount > 0) // in case the user wants to rescan more items, then it will not over write an existing ed card by starting at count = 1: RG
            {
                count = batchCount + 1;
            }

            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)
                {
                    try
                    {
                        if (info.DeviceID == scannerId)
                        {
                            // connect to scanner
                            device = info.Connect();
                            break;
                        }
                    }
                    catch (Exception)
                    {
                        //just catch the exception so the program doesn't 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();

                    if (!useFlatBedScanner)
                    {
                        AdjustScannerSettings(item, 150, 380, 0, 515, 680, 150, 7, 1);
                        //   AdjustScannerSettings(item, 600, 1525, 0, 2100, 2725, 150, 7);
                    }
                    else
                    {
                        // set resolution for flatbed too, or else applciation freezes. see reference;
                        // https://stackoverflow.com/questions/2771743/c-how-to-avoid-wia-error-when-scanning-documents-with-2400dpi-or-more
                        int resolution = 150;
                        int width_pixel = 1250;
                        int height_pixel = 1700;
                        int color_mode = 1;
                        AdjustScannerSettings(item, resolution, 0, 0, width_pixel, height_pixel, 0, 0, color_mode);
                    }
                  
                    WIA.ImageFile image = (WIA.ImageFile)wiaCommonDialog.ShowTransfer(item, wiaFormatBMP, false);

                    if (image != null)
                    {
                        ScannerImageConverter converter = new ScannerImageConverter();
                        BitmapSource ColorScannedImage = converter.InMemoryConvertScannedImage(image);

                        if (!useFlatBedScanner)
                        {                           
                            Bitmap test = converter.BitmapFromSource(ColorScannedImage);
                            Bitmap BitonalScannedImageBMP = converter.ConvertToBitonal(test);
                            Bitmap bitResize = new Bitmap(BitonalScannedImageBMP, new Size(1087, 1401));
                            Bitmap bitResize24 = new Bitmap(bitResize.Width, bitResize.Height, PixelFormat.Format24bppRgb);

                            //create a graphics from the image
                            Graphics g = Graphics.FromImage(bitResize24);

                            //draw the 32bit per pixel image into the 24 bit per pixel image
                            g.DrawImage(bitResize, new Point(0, 0));
                            g.Dispose();

                            ////now save the 24 bit per pixel to disk
                            string fileName = "C:\\ATA\\"+ batchNumber +"-" + count++.ToString() + ".Bmp";
                            bitResize24.Save(fileName, ImageFormat.Bmp);
                        }

                        // add image to output list
                        BitmapSources.Add(ColorScannedImage);
                    }                 
                }
                catch (Exception exc)
                {
                    if (exc.Message == "Exception from HRESULT: 0x80210003")
                    {
                        return BitmapSources;
                    }
                    else if (exc.InnerException != null)
                    {
                        LoggingMediator.Log(exc.InnerException.Message);
                    }
                    else
                    {
                        LoggingMediator.Log(exc.Message);
                    }
                    if(exc.StackTrace != null)
                    {
                        LoggingMediator.Log(exc.StackTrace);
                    }
                    //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()) & WIA_DPS_DOCUMENT_HANDLING_SELECT.FEEDER) != 0)
                        {
                            hasMorePages = ((Convert.ToUInt32(documentHandlingStatus.get_Value()) & WIA_DPS_DOCUMENT_HANDLING_STATUS.FEED_READY) != 0);
                        }
                    }
                }
            }

            return BitmapSources;
        }


        private static void AdjustScannerSettings(IItem scannnerItem, int scanResolutionDPI, int scanStartLeftPixel, int scanStartTopPixel,
        int scanWidthPixels, int scanHeightPixels, int brightnessPercents, int contrastPercents, int colorMode)
        {
            const string WIA_SCAN_COLOR_MODE = "6146";
            const string WIA_HORIZONTAL_SCAN_RESOLUTION_DPI = "6147";
            const string WIA_VERTICAL_SCAN_RESOLUTION_DPI = "6148";
            const string WIA_HORIZONTAL_SCAN_START_PIXEL = "6149";
            const string WIA_VERTICAL_SCAN_START_PIXEL = "6150";
            const string WIA_HORIZONTAL_SCAN_SIZE_PIXELS = "6151";
            const string WIA_VERTICAL_SCAN_SIZE_PIXELS = "6152";
            const string WIA_SCAN_BRIGHTNESS_PERCENTS = "6154";
            const string WIA_SCAN_CONTRAST_PERCENTS = "6155";
            SetWIAProperty(scannnerItem.Properties, WIA_HORIZONTAL_SCAN_RESOLUTION_DPI, scanResolutionDPI);
            SetWIAProperty(scannnerItem.Properties, WIA_VERTICAL_SCAN_RESOLUTION_DPI, scanResolutionDPI);
            SetWIAProperty(scannnerItem.Properties, WIA_HORIZONTAL_SCAN_START_PIXEL, scanStartLeftPixel);
            SetWIAProperty(scannnerItem.Properties, WIA_VERTICAL_SCAN_START_PIXEL, scanStartTopPixel);
            SetWIAProperty(scannnerItem.Properties, WIA_HORIZONTAL_SCAN_SIZE_PIXELS, scanWidthPixels);
            SetWIAProperty(scannnerItem.Properties, WIA_VERTICAL_SCAN_SIZE_PIXELS, scanHeightPixels);
            SetWIAProperty(scannnerItem.Properties, WIA_SCAN_BRIGHTNESS_PERCENTS, brightnessPercents);
            SetWIAProperty(scannnerItem.Properties, WIA_SCAN_CONTRAST_PERCENTS, contrastPercents);
                        SetWIAProperty(scannnerItem.Properties, WIA_SCAN_COLOR_MODE, colorMode);
        }

        private static void SetWIAProperty(IProperties properties, object propName, object propValue)
        {
            Property prop = properties.get_Item(ref propName);
            prop.set_Value(ref propValue);
        }

        /// <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;
        }       
    }

EDIT: ERROR LOG HERE

Exception Stack:
System call failed. (Exception from HRESULT: 0x80010100 (RPC_E_SYS_CALL_FAILED))  Exception Attributes:
    Message: System call failed. (Exception from HRESULT: 0x80010100 (RPC_E_SYS_CALL_FAILED))
    Exception type: System.Runtime.InteropServices.COMException
    Source: MyApplication.DocumentScanner
    Thrown by code in method: ShowTransfer
    Thrown by code in class: ICommonDialog
  Stack Trace:
    Method: WIA.ICommonDialog.ShowTransfer(Item Item, String FormatID, Boolean CancelError)    Line #: 202 -- Method: MyApplication.DocumentScanner.ScannerService.Scan(String scannerId, Boolean useFlatBedScanner, String batchNumber, Int32 batchCount) -- Source File: C:\Projects\Framework.NET\Application\Framework\WPF\MyApplication\ScannerService.cs

Exception 2:

Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))  Exception Attributes:
    Message: Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
    Exception type: System.Runtime.InteropServices.COMException
    Source: Radex.DocumentScanner
    Thrown by code in method: ShowTransfer
    Thrown by code in class: ICommonDialog
 Stack Trace:
        Method: WIA.ICommonDialog.ShowTransfer(Item Item, String FormatID, Boolean CancelError)    Line #: 202 -- Method: MyApplication.DocumentScanner.ScannerService.Scan(String scannerId, Boolean useFlatBedScanner, String batchNumber, Int32 batchCount) -- Source File: C:\Projects\Framework.NET\Application\Framework\WPF\MyApplication\ScannerService.cs

as RandomNumberFun suggested, the Scan methods needs to be called in an async task

AsyncWorker.Execute(() =>
                {
                     List<BitmapSource> images = ScannerService.Scan((string)lbDevices.SelectedItem, true);

                if (images.Count > 0)
                {
                    foreach (var image in images)
                    {
                        AddScannedImage(GetJPGFromImageControl(image));
                    }
                    HasScannedDocument = "Visible";
                }

                    return true;
                }, response =>
                {

                }, this);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM