目前我有一个应用程序,用户可以在其中搜索客户。
问题从这里开始:问题随机发生在 3 个工作站上。用户将搜索客户,然后通过平板扫描仪(epson Perfection v600)扫描纸张,然后保存此信息。用户将重复此过程 X 次,但在随机的时间内,应用程序将抛出以下错误:
内部异常错误:灾难性故障(HRESULT 异常:0x8000FFFF (E_UNEXPECTED)) 异常消息:系统调用失败。 (HRESULT 异常:0x80010100 (RPC_E_SYS_CALL_FAILED)) 在 WIA.ICommonDialog.ShowTransfer(项目项目,字符串 FormatID,布尔 CancelError) 在 C:\Projects\Framework.NET\Application\Framework\WPF\MyScanApp.DocumentScanner\ScannerService.cs 中的 Radex.DocumentScanner.ScannerService.Scan(字符串scannerId,布尔值useFlatBedScanner,字符串batchNumber,Int32 batchCount):第201行
如果我们转到 ScannerService.cs 中的第 201 行..这是抛出错误的代码行:
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 类
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);
我有类似的问题,并且对 C# 非常陌生。
我们有一个用 vb.net 编写的扫描应用程序,它使用 TWIA C# 类通过 WIA 完成实际的扫描工作。我继承了这段代码,因为负责管理它的人离开了公司。
当用户单击 vb.net 项目中的“扫描”按钮时(在选择 ADF 进纸器选项而不是平板之后),它会运行 C# 类中的 Scan() 函数,该类又包含一系列扫描属性设置代码都运行良好,但是当它需要检查他们选择的扫描选项(即 ADF 与平板)时,它会在第二次出现“内存不足”错误下面的代码行...
WIA.ImageFile imgFile = null; imgFile = (ImageFile)WiaCommonDialog.ShowTransfer(item, wiaFormatJPEG, true);
我们刚刚用一台新扫描仪更换了旧扫描仪。当旧扫描仪运行时,同一行代码运行良好,但在新扫描仪中运行失败。假设它一定与驱动程序有关...
我读了你的帖子,发现你也有类似的问题。由于我对 C# 完全不熟悉,您介意发布用于设置后台工作程序的代码吗?您需要的所有代码,包括任何附加的“使用”子句,例如“使用 System.Threading”或其他任何特殊内容类、方法等...以便我可以在我的项目中尝试一下?
我不知道还能尝试什么。运行此代码的 PC 有大量可用 RAM,因此不确定为什么它会抛出该错误。
非常感谢!!
布拉德