private WiaState InitWia() { var device = WiaApi.GetDevice(scanDevice); var item = WiaApi.GetItem(device, settings); WiaApi.Configure(device, item, settings); return(new WiaState(device, item)); }
protected override IEnumerable <ScannedImage> ScanInternal() { using (var eventLoop = new WiaBackgroundEventLoop(ScanProfile, ScanDevice, threadFactory)) { bool supportsFeeder = eventLoop.GetSync(wia => WiaApi.DeviceSupportsFeeder(wia.Device)); if (ScanProfile.PaperSource != ScanSource.Glass && !supportsFeeder) { throw new NoFeederSupportException(); } bool supportsDuplex = eventLoop.GetSync(wia => WiaApi.DeviceSupportsDuplex(wia.Device)); if (ScanProfile.PaperSource == ScanSource.Duplex && !supportsDuplex) { throw new NoDuplexSupportException(); } int pageNumber = 1; int retryCount = 0; bool retry = false; bool cancel = false; do { ScannedImage image; try { if (pageNumber > 1 && ScanProfile.WiaDelayBetweenScans) { int delay = (int)(ScanProfile.WiaDelayBetweenScansSeconds.Clamp(0, 30) * 1000); Thread.Sleep(delay); } image = TransferImage(eventLoop, pageNumber, out cancel); pageNumber++; retryCount = 0; retry = false; } catch (ScanDriverException e) { if (ScanProfile.WiaRetryOnFailure && e.InnerException is COMException && (uint)((COMException)e.InnerException).ErrorCode == 0x80004005 && retryCount < MAX_RETRIES) { Thread.Sleep(1000); retryCount += 1; retry = true; continue; } throw; } catch (Exception e) { throw new ScanDriverUnknownException(e); } if (image != null) { yield return(image); } } while (retry || (!cancel && ScanProfile.PaperSource != ScanSource.Glass)); } }
protected override async Task ScanInternal(ScannedImageSource.Concrete source) { using (var eventLoop = new WiaBackgroundEventLoop(ScanProfile, ScanDevice)) { bool supportsFeeder = eventLoop.GetSync(wia => WiaApi.DeviceSupportsFeeder(wia.Device)); if (ScanProfile.PaperSource != ScanSource.Glass && !supportsFeeder) { throw new NoFeederSupportException(); } bool supportsDuplex = eventLoop.GetSync(wia => WiaApi.DeviceSupportsDuplex(wia.Device)); if (ScanProfile.PaperSource == ScanSource.Duplex && !supportsDuplex) { throw new NoDuplexSupportException(); } int pageNumber = 1; int retryCount = 0; bool retry = false; bool done = false; do { ScannedImage image; try { if (pageNumber > 1 && ScanProfile.WiaDelayBetweenScans) { int delay = (int)(ScanProfile.WiaDelayBetweenScansSeconds.Clamp(0, 30) * 1000); Thread.Sleep(delay); } (image, done) = await TransferImage(eventLoop, pageNumber); pageNumber++; retryCount = 0; retry = false; } catch (ScanDriverException e) { if (ScanProfile.WiaRetryOnFailure && e.InnerException is COMException comError && (uint)comError.ErrorCode == 0x80004005 && retryCount < MAX_RETRIES) { Thread.Sleep(1000); retryCount += 1; retry = true; continue; } throw; } if (image != null) { source.Put(image); } } while (!CancelToken.IsCancellationRequested && (retry || !done && ScanProfile.PaperSource != ScanSource.Glass)); } }
protected override IEnumerable <ScannedImage> ScanInternal() { using (var eventLoop = new WiaBackgroundEventLoop(ScanProfile, ScanDevice, threadFactory)) { bool supportsFeeder = eventLoop.GetSync(wia => WiaApi.DeviceSupportsFeeder(wia.Device)); if (ScanProfile.PaperSource != ScanSource.Glass && !supportsFeeder) { throw new NoFeederSupportException(); } bool supportsDuplex = eventLoop.GetSync(wia => WiaApi.DeviceSupportsDuplex(wia.Device)); if (ScanProfile.PaperSource == ScanSource.Duplex && !supportsDuplex) { throw new NoDuplexSupportException(); } int pageNumber = 1; int retryCount = 0; bool retry = false; bool cancel = false; do { ScannedImage image; try { image = TransferImage(eventLoop, pageNumber, out cancel); pageNumber++; Debug.WriteLine("Succeeded with retry count {0}", retryCount); retryCount = 0; retry = false; } catch (ScanDriverException e) { if (e.InnerException is COMException && (uint)((COMException)e.InnerException).ErrorCode == 0x80004005 && retryCount < 10) { Thread.Sleep(1000); retryCount += 1; Debug.WriteLine("Retrying {0}", retryCount); retry = true; continue; } throw; } catch (Exception e) { throw new ScanDriverUnknownException(e); } if (image != null) { yield return(image); } } while (retry || (!cancel && ScanProfile.PaperSource != ScanSource.Glass)); } }
private Stream DoTransfer(int pageNumber, WiaBackgroundEventLoop eventLoop, string format) { var invoker = (FormBase)DialogParent; if (eventLoop.GetSync(wia => wia.Item) == null) { return(null); } if (ScanParams.NoUI) { return(eventLoop.GetSync(wia => WiaApi.Transfer(wia, format, false))); } if (pageNumber == 1) { // The only downside of the common dialog is that it steals focus. // If this is the first page, then the user has just pressed the scan button, so that's not // an issue and we can use it and get the benefits of progress display and immediate cancellation. return(ScanParams.Modal ? eventLoop.GetSync(wia => invoker.InvokeGet(() => WiaApi.Transfer(wia, format, true))) : eventLoop.GetSync(wia => WiaApi.Transfer(wia, format, true))); } // For subsequent pages, we don't want to take focus in case the user has switched applications, // so we use the custom form. var form = formFactory.Create <FScanProgress>(); var waitHandle = new AutoResetEvent(false); form.PageNumber = pageNumber; form.Transfer = () => eventLoop.GetSync(wia => WiaApi.Transfer(wia, format, false)); form.Closed += (sender, args) => waitHandle.Set(); if (ScanParams.Modal) { invoker.Invoke(() => form.ShowDialog(DialogParent)); } else { invoker.Invoke(() => form.Show(DialogParent)); } waitHandle.WaitOne(); if (form.Exception != null) { WiaApi.ThrowDeviceError(form.Exception); } if (form.DialogResult == DialogResult.Cancel) { return(null); } return(form.ImageStream); }
protected override IEnumerable <IScannedImage> ScanInternal() { using (var eventLoop = new WiaBackgroundEventLoop(ScanSettings, ScanDevice)) { bool supportsFeeder = eventLoop.GetSync(wia => WiaApi.DeviceSupportsFeeder(wia.Device)); if (ScanSettings.PaperSource != ScanSource.Glass && !supportsFeeder) { throw new NoFeederSupportException(); } int pageNumber = 1; while (true) { bool feederReady = eventLoop.GetSync(wia => WiaApi.DeviceFeederReady(wia.Device)); if (ScanSettings.PaperSource != ScanSource.Glass && !feederReady) { if (pageNumber == 1) { throw new NoPagesException(); } break; } IScannedImage image; try { image = TransferImage(eventLoop, pageNumber++); } catch (ScanDriverException) { throw; } catch (Exception e) { throw new ScanDriverUnknownException(e); } if (image == null) { break; } yield return(image); if (ScanSettings.PaperSource == ScanSource.Glass) { break; } } } }
protected override IEnumerable <ScannedImage> ScanInternal() { using (var eventLoop = new WiaBackgroundEventLoop(ScanProfile, ScanDevice, threadFactory)) { bool supportsFeeder = eventLoop.GetSync(wia => WiaApi.DeviceSupportsFeeder(wia.Device)); if (ScanProfile.PaperSource != ScanSource.Glass && !supportsFeeder) { throw new NoFeederSupportException(); } bool supportsDuplex = eventLoop.GetSync(wia => WiaApi.DeviceSupportsDuplex(wia.Device)); if (ScanProfile.PaperSource == ScanSource.Duplex && !supportsDuplex) { throw new NoDuplexSupportException(); } int pageNumber = 1; bool cancel; do { ScannedImage image; try { image = TransferImage(eventLoop, pageNumber++, out cancel); } catch (ScanDriverException) { throw; } catch (Exception e) { throw new ScanDriverUnknownException(e); } if (image != null) { yield return(image); } } while (!cancel && ScanProfile.PaperSource != ScanSource.Glass); } }
public Stream Transfer(int pageNumber, WiaBackgroundEventLoop eventLoop, string format) { if (eventLoop.GetSync(wia => wia.Item) == null) { return(null); } if (pageNumber == 1) { // The only downside of the common dialog is that it steals focus. // If this is the first page, then the user has just pressed the scan button, so that's not // an issue and we can use it and get the benefits of progress display and immediate cancellation. ImageFile imageFile = eventLoop.GetSync(wia => (ImageFile) new CommonDialogClass().ShowTransfer(wia.Item, format)); if (imageFile == null) { return(null); } return(new MemoryStream((byte[])imageFile.FileData.get_BinaryData())); } // For subsequent pages, we don't want to take focus in case the user has switched applications, // so we use the custom form. var form = formFactory.Create <FScanProgress>(); form.PageNumber = pageNumber; form.EventLoop = eventLoop; form.Format = format; form.ShowDialog(); if (form.Exception != null) { WiaApi.ThrowDeviceError(form.Exception); } if (form.DialogResult == DialogResult.Cancel) { return(null); } return(form.ImageStream); }
public void DoSync(Action <WiaState> action) { Exception error = null; form.Invoke(new Action(() => { try { if (wiaState == null) { wiaState = InitWia(); } action(wiaState); } catch (Exception ex) { error = ex; } })); if (error != null) { WiaApi.ThrowDeviceError(error); } }
protected override ScanDevice PromptForDeviceInternal() { return(WiaApi.PromptForDevice()); }
protected override List <ScanDevice> GetDeviceListInternal() { return(WiaApi.GetScanDeviceList()); }
protected override List <ScanDevice> GetDeviceListInternal() => WiaApi.GetScanDeviceList();
protected override ScanDevice PromptForDeviceInternal() => WiaApi.PromptForScanDevice();