2

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
Pacheko
  • 133
  • 1
  • 1
  • 13
  • Sounds like it's a communication error with the scanner if it's a true random event. Can you check the device manager logs if it has anything in it. – juanvan Jun 11 '21 at 13:05
  • @juanvan sadly in the logs, there is no error/event/ warning or anything related to it on the datetime stamp when the error occurred – Pacheko Jun 11 '21 at 14:03
  • Can you do a retry on error? – juanvan Jun 11 '21 at 17:02
  • 1
    @juanvan YEs, I've finally received a bit more documented error log: Please see the edited section – Pacheko Jun 15 '21 at 19:30
  • 2
    Would adding async/wait pattern to your for loop in `Scan()` make it work? I wonder if, you are asking to use memory in use that .net does not know about. – RandomNumberFun Jun 16 '21 at 16:58
  • 1
    @RandomNumberFun Unbelievable, your suggestion immediately solved the problem. After inserting the SCAN method in a AsyncWorker.Execute, which runs in a async thread, the bug/ error stopped appearing on all workstations/terminals. It makes sense, but at the same time of all applications that I've made, this is the first time encountering this specific issue with WIA.. – Pacheko Jun 16 '21 at 20:19
  • 1
    My guess would be the difference (deltas) in file size, processing time, network lag, or any other variances that may bound the process and cause the processing time/memory freeing difference. Not sure if that makes sense but that was my first guess. Another approach might be to remove the async call, and try to force garbage collection as part of the Scan() loop. Not to say this is better, but doing this might help you narrow down where the issue is coming from. I would say just don't worry about it and use async. – RandomNumberFun Jun 18 '21 at 08:00
  • 1
    @RandomNumberFun , Yes I agree too.... I've decided to force GC after the scan method, since i noticed that Memory usage was slowly increasing with time and not being released when viewmodel was closed (despite releasing/clearing used objects)... Thank you very much for your feedback – Pacheko Jun 18 '21 at 12:43

1 Answers1

1

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);
Pacheko
  • 133
  • 1
  • 1
  • 13