簡體   English   中英

C# Windows 圖像采集掃描在隨機掃描間隔拋出錯誤

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

目前我有一個用戶搜索客戶的應用程序。

問題從這里開始:問題隨機發生在 3 個工作站。 用戶將搜索客戶,然后通過平板掃描儀(epson perfect v600)掃描紙張,然后保存此信息。 用戶將重復此過程 X 時間,但隨機數量,應用程序將拋出以下錯誤:

INNEREXCEPTION 錯誤:災難性故障(來自 HRESULT 的異常:0x8000FFFF (E_UNEXPECTED)) 異常消息:系統調用失敗。 (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

如果我們 go 到第 201 行,在 ScannerService.cs.. 這是引發錯誤的代碼行:

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

有沒有人遇到過這個錯誤,或者知道如何解決它? 下面是我調用掃描服務啟動掃描程序的按鈕代碼。 任何反饋都非常感謝,因為這個問題讓我發瘋

掃描按鈕:

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

此處遵循 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;
        }       
    }

編輯:這里的錯誤日志

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

例外 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

正如 RandomNumberFun 建議的那樣,需要在異步任務中調用 Scan 方法

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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM