public bool SavePdf(string fileName, DateTime dateTime, ICollection <IScannedImage> images, PdfSettings pdfSettings, string ocrLanguageCode, Func <int, bool> progressCallback) { var subFileName = fileNamePlaceholders.SubstitutePlaceholders(fileName, dateTime); if (File.Exists(subFileName)) { if (overwritePrompt.ConfirmOverwrite(subFileName) != DialogResult.Yes) { return(false); } } try { pdfExporter.Export(subFileName, images, pdfSettings, ocrLanguageCode, progressCallback); return(true); } catch (UnauthorizedAccessException) { errorOutput.DisplayError(MiscResources.DontHavePermission); } catch (IOException ex) { Log.ErrorException(MiscResources.ErrorSaving, ex); errorOutput.DisplayError(MiscResources.ErrorSaving); } return(false); }
private void ChooseDevice(string driverName) { var driver = driverFactory.Create(driverName); try { driver.DialogParent = this; ScanDevice device = driver.PromptForDevice(); if (device != null) { if (string.IsNullOrEmpty(txtName.Text) || CurrentDevice != null && CurrentDevice.Name == txtName.Text) { txtName.Text = device.Name; } CurrentDevice = device; } } catch (ScanDriverException e) { if (e is ScanDriverUnknownException) { Log.ErrorException(e.Message, e.InnerException); } errorOutput.DisplayError(e.Message); } }
public IEnumerable <ScannedImage> Import(string filePath, ImportParams importParams, Func <int, int, bool> progressCallback) { if (!progressCallback(0, 0)) { return(Enumerable.Empty <ScannedImage>()); } int passwordAttempts = 0; bool aborted = false; int i = 0; try { PdfDocument document = PdfReader.Open(filePath, PdfDocumentOpenMode.Import, args => { if (!pdfPasswordProvider.ProvidePassword(Path.GetFileName(filePath), passwordAttempts++, out args.Password)) { args.Abort = true; aborted = true; } }); if (passwordAttempts > 0 && !document.SecuritySettings.HasOwnerPermissions && !document.SecuritySettings.PermitExtractContent) { errorOutput.DisplayError(string.Format(MiscResources.PdfNoPermissionToExtractContent, Path.GetFileName(filePath))); return(Enumerable.Empty <ScannedImage>()); } if (document.Info.Creator != MiscResources.NAPS2 && document.Info.Author != MiscResources.NAPS2) { pdfRenderer.ThrowIfCantRender(); return(importParams.Slice.Indices(document.PageCount) .Select(index => document.Pages[index]) .TakeWhile(page => progressCallback(i++, document.PageCount)) .Select(page => ExportRawPdfPage(page, importParams))); } return(importParams.Slice.Indices(document.PageCount) .Select(index => document.Pages[index]) .TakeWhile(page => progressCallback(i++, document.PageCount)) .SelectMany(page => GetImagesFromPage(page, importParams))); } catch (ImageRenderException e) { errorOutput.DisplayError(string.Format(MiscResources.ImportErrorNAPS2Pdf, Path.GetFileName(filePath))); Log.ErrorException("Error importing PDF file.", e); return(Enumerable.Empty <ScannedImage>()); } catch (Exception e) { if (!aborted) { errorOutput.DisplayError(string.Format(MiscResources.ImportErrorCouldNot, Path.GetFileName(filePath))); Log.ErrorException("Error importing PDF file.", e); } return(Enumerable.Empty <ScannedImage>()); } }
private void FAuthorize_Load(object sender, EventArgs e) { MaximumSize = new Size(Math.Max(lblWaiting.Width + 142, 272), Height); MinimumSize = new Size(Math.Max(lblWaiting.Width + 142, 272), Height); cancelTokenSource = new CancellationTokenSource(); Task.Factory.StartNew(() => { try { OauthProvider.AcquireToken(cancelTokenSource.Token); Invoke(() => { DialogResult = DialogResult.OK; Close(); }); } catch (OperationCanceledException) { } catch (Exception ex) { errorOutput.DisplayError(MiscResources.AuthError, ex); Log.ErrorException("Error acquiring Oauth token", ex); Invoke(() => { DialogResult = DialogResult.Cancel; Close(); }); } }, TaskCreationOptions.LongRunning); }
public bool Save(AutoSaveSettings settings, List <ScannedImage> images, ISaveNotify notify) { if (appConfigManager.Config.DisableAutoSave) { return(false); } try { bool ok = true; DateTime now = DateTime.Now; int i = 0; string firstFileSaved = null; var scans = SaveSeparatorHelper.SeparateScans(new[] { images }, settings.Separator).ToList(); foreach (var imageList in scans) { if (!SaveOneFile(settings, now, i++, imageList, scans.Count == 1 ? notify : null, ref firstFileSaved)) { ok = false; } } if (notify != null && scans.Count > 1 && ok) { // Can't just do images.Count because that includes patch codes int imageCount = scans.SelectMany(x => x).Count(); notify.ImagesSaved(imageCount, firstFileSaved); } return(ok); } catch (Exception ex) { Log.ErrorException(MiscResources.AutoSaveError, ex); errorOutput.DisplayError(MiscResources.AutoSaveError); return(false); } }
/// <summary> /// Sends an email described by the given message object. /// </summary> /// <param name="message">The object describing the email message.</param> /// <param name="progressCallback"></param> /// <param name="cancelToken"></param> /// <returns>Returns true if the message was sent, false if the user aborted.</returns> public async Task <bool> SendEmail(EmailMessage message, ProgressHandler progressCallback, CancellationToken cancelToken) { return(await Task.Factory.StartNew(() => { MapiSendMailReturnCode returnCode; if (UseWorker) { using (var worker = workerServiceFactory.Create()) { returnCode = worker.Service.SendMapiEmail(message); } } else { returnCode = mapiWrapper.SendEmail(message); } // Process the result if (returnCode == MapiSendMailReturnCode.UserAbort) { return false; } if (returnCode != MapiSendMailReturnCode.Success) { Log.Error("Error sending email. MAPI error code: {0}", returnCode); errorOutput.DisplayError(MiscResources.EmailError, $"MAPI returned error code: {returnCode}"); return false; } return true; })); }
private void Import() { var ofd = new OpenFileDialog { Multiselect = true, CheckFileExists = true }; if (ofd.ShowDialog() == DialogResult.OK) { foreach (var fileName in ofd.FileNames.OrderBy(x => x)) { // TODO: Run in thread, and show a dialog (just like exporting) // Need to provide count somehow (progress callback). count = # files or # pages try { var images = scannedImageImporter.Import(fileName); foreach (var img in images) { imageList.Images.Add(img); AppendThumbnail(img); thumbnailList1.Refresh(); changeTracker.HasUnsavedChanges = true; Application.DoEvents(); } } catch (Exception ex) { Log.ErrorException(string.Format(MiscResources.ImportErrorCouldNot, Path.GetFileName(fileName)), ex); errorOutput.DisplayError(string.Format(MiscResources.ImportErrorCouldNot, Path.GetFileName(fileName))); } } } }
public T Create <T>() where T : IOperation { var op = kernel.Get <T>(); op.Error += (sender, args) => errorOutput.DisplayError(args.ErrorMessage, args.Exception); return(op); }
private void DownloadCompleted(object sender, AsyncCompletedEventArgs e) { try { if (e.Cancelled) { return; } if (e.Error != null) { e.Error.PreserveStackTrace(); throw e.Error; } if (!VerifyHash()) { Log.Error($"Update error for {update.Name}: hash does not match"); errorOutput.DisplayError(MiscResources.UpdateError); return; } if (!VerifySignature()) { Log.Error($"Update error for {update.Name}: signature does not validate"); errorOutput.DisplayError(MiscResources.UpdateError); return; } #if STANDALONE InstallZip(); #else InstallExe(); #endif } catch (Exception ex) { Log.ErrorException("Update error", ex); errorOutput.DisplayError(MiscResources.UpdateError); return; } finally { InvokeFinished(); waitHandle.Set(); } RecoveryImage.DisableRecoveryCleanup = true; Application.OpenForms.OfType <Form>().FirstOrDefault()?.Close(); }
private async Task DoBatchScan() { try { await batchScanPerformer.PerformBatchScan(BatchSettings, this, image => SafeInvoke(() => ImageCallback(image)), ProgressCallback, cts.Token); SafeInvoke(() => { lblStatus.Text = cts.IsCancellationRequested ? MiscResources.BatchStatusCancelled : MiscResources.BatchStatusComplete; }); } catch (ScanDriverException ex) { if (ex is ScanDriverUnknownException) { Log.ErrorException("Error in batch scan", ex); errorOutput.DisplayError(ex.Message, ex); } else { errorOutput.DisplayError(ex.Message); } } catch (Exception ex) { Log.ErrorException("Error in batch scan", ex); errorOutput.DisplayError(MiscResources.BatchError, ex); SafeInvoke(() => { lblStatus.Text = MiscResources.BatchStatusError; }); } SafeInvoke(() => { batchRunning = false; cts = new CancellationTokenSource(); btnStart.Enabled = true; btnCancel.Enabled = true; btnCancel.Text = MiscResources.Close; EnableDisableSettings(true); Activate(); }); }
public IEnumerable <IScannedImage> Import(string filePath) { int passwordAttempts = 0; bool aborted = false; try { PdfDocument document = PdfReader.Open(filePath, PdfDocumentOpenMode.ReadOnly, args => { if (!pdfPasswordProvider.ProvidePassword(Path.GetFileName(filePath), passwordAttempts++, out args.Password)) { args.Abort = true; aborted = true; } }); if (document.Info.Creator != MiscResources.NAPS2 && document.Info.Author != MiscResources.NAPS2) { errorOutput.DisplayError(string.Format(MiscResources.ImportErrorNAPS2Pdf, Path.GetFileName(filePath))); return(Enumerable.Empty <IScannedImage>()); } if (passwordAttempts > 0 && !document.SecuritySettings.HasOwnerPermissions && !document.SecuritySettings.PermitExtractContent) { errorOutput.DisplayError(string.Format(MiscResources.PdfNoPermissionToExtractContent, Path.GetFileName(filePath))); return(Enumerable.Empty <IScannedImage>()); } return(document.Pages.Cast <PdfPage>().SelectMany(GetImagesFromPage)); } catch (NotImplementedException e) { errorOutput.DisplayError(string.Format(MiscResources.ImportErrorNAPS2Pdf, Path.GetFileName(filePath))); Log.ErrorException("Error importing PDF file.", e); return(Enumerable.Empty <IScannedImage>()); } catch (Exception e) { if (!aborted) { errorOutput.DisplayError(string.Format(MiscResources.ImportErrorCouldNot, Path.GetFileName(filePath))); Log.ErrorException("Error importing PDF file.", e); } return(Enumerable.Empty <IScannedImage>()); } }
private void DoBatchScan() { try { batchScanPerformer.PerformBatchScan(BatchSettings, this, image => Invoke(() => ImageCallback(image)), ProgressCallback()); Invoke(() => { lblStatus.Text = cancelBatch ? MiscResources.BatchStatusCancelled : MiscResources.BatchStatusComplete; }); } catch (ScanDriverException ex) { if (ex is ScanDriverUnknownException) { Log.ErrorException("Error in batch scan", ex); errorOutput.DisplayError(ex.Message, ex); } else { errorOutput.DisplayError(ex.Message); } } catch (Exception ex) { Log.ErrorException("Error in batch scan", ex); errorOutput.DisplayError(MiscResources.BatchError, ex); Invoke(() => { lblStatus.Text = MiscResources.BatchStatusError; }); } Invoke(() => { batchRunning = false; cancelBatch = false; btnStart.Enabled = true; btnCancel.Enabled = true; btnCancel.Text = MiscResources.Close; EnableDisableSettings(true); Activate(); }); }
public bool ProvidePassword(string fileName, int attemptCount, out string password) { password = PasswordToProvide ?? ""; if (attemptCount > 0) { errorOutput.DisplayError(PasswordToProvide == null ? ConsoleResources.ImportErrorNoPassword : ConsoleResources.ImportErrorWrongPassword); return(false); } return(true); }
private bool PreCheckOverwriteFile() { if (options.OutputPath == null) { // Email, so no check needed return(true); } var subPath = fileNamePlaceholders.SubstitutePlaceholders(options.OutputPath, startTime); if (!IsPdfFile(subPath) || !File.Exists(subPath) || options.ForceOverwrite) { return(true); } errorOutput.DisplayError(string.Format(ConsoleResources.FileAlreadyExists, Path.GetFullPath(subPath))); return(false); }
public DialogResult ConfirmOverwrite(string path) { if (ForceOverwrite) { return(DialogResult.Yes); } else { errorOutput.DisplayError(string.Format(ConsoleResources.FileAlreadyExists, path)); return(DialogResult.No); } }
/// <summary> /// Saves the provided collection of images to a file with the given name. The image type is inferred from the file extension. /// If multiple images are provided, they will be saved to files with numeric identifiers, e.g. img1.jpg, img2.jpg, etc.. /// </summary> /// <param name="fileName">The name of the file to save. For multiple images, this is modified by appending a number before the extension.</param> /// <param name="images">The collection of images to save.</param> /// <param name="overwritePredicate">A predicate that, given the full name/path of a file that already exists, returns true if it should be overwritten, or false if it should be skipped.</param> public void SaveImages(string fileName, ICollection <IScannedImage> images, Func <string, bool> overwritePredicate) { try { ImageFormat format = GetImageFormat(fileName); //if (Equals(format, ImageFormat.Tiff)) //{ // if (File.Exists(fileName)) // { // // Overwrite? // if (!overwritePredicate(Path.GetFullPath(fileName))) // { // // No, so skip it // return; // } // } // Image[] bitmaps = images.Select(x => (Image)x.GetImage()).ToArray(); // TiffHelper.SaveMultipage(bitmaps, fileName); // foreach (Image bitmap in bitmaps) // { // bitmap.Dispose(); // } // return; //} var fileNames = imageFileNamer.GetFileNames(fileName, images.Count).GetEnumerator(); foreach (IScannedImage img in images) { using (Bitmap baseImage = img.GetImage()) { fileNames.MoveNext(); if (File.Exists(fileNames.Current)) { // Overwrite? if (!overwritePredicate(Path.GetFullPath(fileNames.Current))) { // No, so skip it continue; } } baseImage.Save(fileNames.Current, format); } } } catch (UnauthorizedAccessException) { errorOutput.DisplayError("No tienes permisos para guardar archivos en esa ubicaciĆ³n."); } }
/// <summary> /// Sends an email described by the given message object. /// </summary> /// <param name="message">The object describing the email message.</param> /// <returns>Returns true if the message was sent, false if the user aborted.</returns> public bool SendEmail(EmailMessage message) { // Translate files & recipients to unmanaged MAPI structures using (var files = Unmanaged.CopyOf(GetFiles(message))) using (var recips = Unmanaged.CopyOf(GetRecips(message))) { // Create a MAPI structure for the entirety of the message var mapiMessage = new MapiMessage { subject = message.Subject, noteText = message.BodyText, recips = recips, recipCount = recips.Length, files = files, fileCount = files.Length }; // Determine the flags used to send the message var flags = MapiSendMailFlags.None; if (!message.AutoSend) { flags |= MapiSendMailFlags.Dialog; } if (!message.AutoSend || !message.SilentSend) { flags |= MapiSendMailFlags.LogonUI; } // Send the message var returnCode = MAPISendMail(IntPtr.Zero, IntPtr.Zero, mapiMessage, flags, 0); // Process the result if (returnCode == MapiSendMailReturnCode.UserAbort) { return(false); } if (returnCode != MapiSendMailReturnCode.Success) { Log.Error("Error sending email. MAPI error code: {0}", returnCode); errorOutput.DisplayError(MiscResources.EmailError); return(false); } return(true); } }
/// <summary> /// Sends an email described by the given message object. /// </summary> /// <param name="message">The object describing the email message.</param> /// <param name="progressCallback"></param> /// <param name="cancelToken"></param> /// <returns>Returns true if the message was sent, false if the user aborted.</returns> public async Task <bool> SendEmail(EmailMessage message, ProgressHandler progressCallback, CancellationToken cancelToken) { return(await Task.Factory.StartNew(() => { MapiSendMailReturnCode returnCode; if (UseWorker && !mapiWrapper.CanLoadClient) { using (var worker = workerServiceFactory.Create()) { returnCode = worker.Service.SendMapiEmail(message); } } else { returnCode = mapiWrapper.SendEmail(message); // It's difficult to get 32/64 bit right when using mapi32.dll. This can help sometimes. // https://docs.microsoft.com/en-us/office/client-developer/outlook/mapi/building-mapi-applications-on-32-bit-and-64-bit-platforms if (UseWorker && returnCode == MapiSendMailReturnCode.Failure) { using (var worker = workerServiceFactory.Create()) { returnCode = worker.Service.SendMapiEmail(message); } } } // Process the result if (returnCode == MapiSendMailReturnCode.UserAbort) { return false; } if (returnCode != MapiSendMailReturnCode.Success) { Log.Error("Error sending email. MAPI error code: {0}", returnCode); errorOutput.DisplayError(MiscResources.EmailError, $"MAPI returned error code: {returnCode}"); return false; } return true; })); }
public void PerformScan(ExtendedScanSettings scanSettings, IWin32Window dialogParent, IScanReceiver scanReceiver) { var driver = driverFactory.Create(scanSettings.DriverName); driver.DialogParent = dialogParent; driver.ScanSettings = scanSettings; try { if (scanSettings.Device == null) { // The profile has no device specified, so prompt the user to choose one var device = driver.PromptForDevice(); if (device == null) { // User cancelled return; } driver.ScanDevice = device; } else { // The profile has a device specified, so use it driver.ScanDevice = scanSettings.Device; } foreach (IScannedImage scannedImage in driver.Scan()) { scanReceiver.ReceiveScannedImage(scannedImage); Application.DoEvents(); } } catch (ScanDriverException e) { if (e is ScanDriverUnknownException) { Log.ErrorException(e.Message, e.InnerException); } errorOutput.DisplayError(e.Message); } }
/// <summary> /// Sends an email described by the given message object. /// </summary> /// <param name="message">The object describing the email message.</param> /// <param name="progressCallback"></param> /// <param name="cancelToken"></param> /// <returns>Returns true if the message was sent, false if the user aborted.</returns> public async Task <bool> SendEmail(EmailMessage message, ProgressHandler progressCallback, CancellationToken cancelToken) { var configuredClientName = userConfigManager.Config.EmailSetup?.SystemProviderName; MapiSendMailReturnCode EmailInProc(string clientName) => mapIWrapper.SendEmail(clientName, message); MapiSendMailReturnCode EmailByWorker(string clientName) { using (var worker = workerServiceFactory.Create()) { return(worker.Service.SendMapiEmail(clientName, message)); } } return(await Task.Factory.StartNew(() => { // It's difficult to get 32/64 bit right when using mapi32.dll: // https://docs.microsoft.com/en-us/office/client-developer/outlook/mapi/building-mapi-applications-on-32-bit-and-64-bit-platforms // Also some people have had issues with bad DLL paths (?), so we can fall back to mapi32.dll. var emailFunctions = new List <Func <MapiSendMailReturnCode> >(); if (configuredClientName != null) { if (mapIWrapper.CanLoadClient(configuredClientName)) { emailFunctions.Add(() => EmailInProc(configuredClientName)); } if (UseWorker) { emailFunctions.Add(() => EmailByWorker(configuredClientName)); } } if (mapIWrapper.CanLoadClient(null)) { emailFunctions.Add(() => EmailInProc(null)); } if (UseWorker) { emailFunctions.Add(() => EmailByWorker(null)); } var returnCode = MapiSendMailReturnCode.Failure; foreach (var func in emailFunctions) { returnCode = func(); if (returnCode != MapiSendMailReturnCode.Failure) { break; } } // Process the result if (returnCode == MapiSendMailReturnCode.UserAbort) { return false; } if (returnCode == MapiSendMailReturnCode.Success) { return true; } Log.Error("Error sending email. MAPI error code: {0}", returnCode); errorOutput.DisplayError(MiscResources.EmailError, $"MAPI returned error code: {returnCode}"); return false; })); }
void operation_Error(object sender, OperationErrorEventArgs e) { Invoke(() => errorOutput.DisplayError(e.ErrorMessage, e.Exception)); }
public void PerformScan(ScanProfile scanProfile, ScanParams scanParams, IWin32Window dialogParent, ISaveNotify notify, Action <ScannedImage> imageCallback) { var driver = driverFactory.Create(scanProfile.DriverName); driver.DialogParent = dialogParent; driver.ScanProfile = scanProfile; driver.ScanParams = scanParams; try { if (scanProfile.Device == null) { // The profile has no device specified, so prompt the user to choose one var device = driver.PromptForDevice(); if (device == null) { // User cancelled return; } if (appConfigManager.Config.AlwaysRememberDevice) { scanProfile.Device = device; profileManager.Save(); } driver.ScanDevice = device; } else { // The profile has a device specified, so use it driver.ScanDevice = scanProfile.Device; } bool doAutoSave = !scanParams.NoAutoSave && !appConfigManager.Config.DisableAutoSave && scanProfile.EnableAutoSave && scanProfile.AutoSaveSettings != null; if (doAutoSave) { if (scanProfile.AutoSaveSettings.ClearImagesAfterSaving) { // Auto save without piping images var images = driver.Scan().ToList(); if (autoSave.Save(scanProfile.AutoSaveSettings, images, notify)) { foreach (ScannedImage img in images) { img.Dispose(); } } else { // Fallback in case auto save failed; pipe all the images back at once foreach (ScannedImage img in images) { imageCallback(img); } } } else { // Basic auto save, so keep track of images as we pipe them and try to auto save afterwards var images = new List <ScannedImage>(); foreach (ScannedImage scannedImage in driver.Scan()) { imageCallback(scannedImage); images.Add(scannedImage); } autoSave.Save(scanProfile.AutoSaveSettings, images, notify); } } else { // No auto save, so just pipe images back as we get them foreach (ScannedImage scannedImage in driver.Scan()) { imageCallback(scannedImage); } } } catch (ScanDriverException e) { if (e is ScanDriverUnknownException) { Log.ErrorException(e.Message, e.InnerException); errorOutput.DisplayError(e.Message, e); } else { errorOutput.DisplayError(e.Message); } } }
void operation_Error(object sender, OperationErrorEventArgs e) { errorOutput.DisplayError(e.ErrorMessage); }
/// <summary> /// Saves the provided collection of images to a file with the given name. The image type is inferred from the file extension. /// If multiple images are provided, they will be saved to files with numeric identifiers, e.g. img1.jpg, img2.jpg, etc.. /// </summary> /// <param name="fileName">The name of the file to save. For multiple images, this is modified by appending a number before the extension.</param> /// <param name="dateTime"></param> /// <param name="images">The collection of images to save.</param> public void SaveImages(string fileName, DateTime dateTime, ICollection <IScannedImage> images, Func <int, bool> progressCallback) { try { var subFileName = fileNamePlaceholders.SubstitutePlaceholders(fileName, dateTime); ImageFormat format = GetImageFormat(subFileName); if (Equals(format, ImageFormat.Tiff)) { if (File.Exists(subFileName)) { if (overwritePrompt.ConfirmOverwrite(subFileName) != DialogResult.Yes) { return; } } Image[] bitmaps = images.Select(x => (Image)x.GetImage()).ToArray(); TiffHelper.SaveMultipage(bitmaps, subFileName); foreach (Image bitmap in bitmaps) { bitmap.Dispose(); } return; } int i = 1; int digits = (int)Math.Floor(Math.Log10(images.Count)) + 1; foreach (IScannedImage img in images) { if (!progressCallback(i)) { return; } if (images.Count == 1 && File.Exists(subFileName)) { var dialogResult = overwritePrompt.ConfirmOverwrite(subFileName); if (dialogResult == DialogResult.No) { continue; } if (dialogResult == DialogResult.Cancel) { return; } } using (Bitmap baseImage = img.GetImage()) { if (images.Count == 1) { DoSaveImage(baseImage, subFileName, format); } else { var fileNameN = fileNamePlaceholders.SubstitutePlaceholders(fileName, dateTime, true, i - 1, digits); DoSaveImage(baseImage, fileNameN, format); } } i++; } } catch (UnauthorizedAccessException) { errorOutput.DisplayError(MiscResources.DontHavePermission); } catch (IOException ex) { Log.ErrorException(MiscResources.ErrorSaving, ex); errorOutput.DisplayError(MiscResources.ErrorSaving); } }
public async Task PerformScan(ScanProfile scanProfile, ScanParams scanParams, IWin32Window dialogParent, ISaveNotify notify, Action <ScannedImage> imageCallback, CancellationToken cancelToken = default) { var driver = driverFactory.Create(scanProfile.DriverName); driver.DialogParent = dialogParent; driver.ScanProfile = scanProfile; driver.ScanParams = scanParams; driver.CancelToken = cancelToken; try { if (scanProfile.Device == null) { // The profile has no device specified, so prompt the user to choose one var device = driver.PromptForDevice(); if (device == null) { // User cancelled return; } if (appConfigManager.Config.AlwaysRememberDevice) { scanProfile.Device = device; profileManager.Save(); } driver.ScanDevice = device; } else { // The profile has a device specified, so use it driver.ScanDevice = scanProfile.Device; } // Start the scan int imageCount = 0; var source = driver.Scan().Then(img => imageCount++); bool doAutoSave = !scanParams.NoAutoSave && !appConfigManager.Config.DisableAutoSave && scanProfile.EnableAutoSave && scanProfile.AutoSaveSettings != null; if (doAutoSave) { if (scanProfile.AutoSaveSettings.ClearImagesAfterSaving) { // Auto save without piping images var images = await source.ToList(); if (await autoSave.Save(scanProfile.AutoSaveSettings, images, notify)) { foreach (ScannedImage img in images) { img.Dispose(); } } else { // Fallback in case auto save failed; pipe all the images back at once foreach (ScannedImage img in images) { imageCallback(img); } } } else { // Basic auto save, so keep track of images as we pipe them and try to auto save afterwards var images = new List <ScannedImage>(); await source.ForEach(scannedImage => { imageCallback(scannedImage); images.Add(scannedImage); }); await autoSave.Save(scanProfile.AutoSaveSettings, images, notify); } } else { // No auto save, so just pipe images back as we get them await source.ForEach(imageCallback); } if (imageCount > 0) { Log.Event(EventType.Scan, new Event { Name = MiscResources.Scan, Pages = imageCount, DeviceName = scanProfile.Device?.Name, ProfileName = scanProfile.DisplayName, BitDepth = scanProfile.BitDepth.Description() }); } } catch (ScanDriverException e) { if (e is ScanDriverUnknownException) { Log.ErrorException(e.Message, e.InnerException); errorOutput.DisplayError(e.Message, e); } else { errorOutput.DisplayError(e.Message); } } }
public ScannedImageSource Import(string filePath, ImportParams importParams, ProgressHandler progressCallback, CancellationToken cancelToken) { var source = new ScannedImageSource.Concrete(); Task.Factory.StartNew(async() => { if (cancelToken.IsCancellationRequested) { source.Done(); } int passwordAttempts = 0; bool aborted = false; int i = 0; try { PdfDocument document = PdfReader.Open(filePath, PdfDocumentOpenMode.Import, args => { if (!pdfPasswordProvider.ProvidePassword(Path.GetFileName(filePath), passwordAttempts++, out args.Password)) { args.Abort = true; aborted = true; } }); if (passwordAttempts > 0 && !document.SecuritySettings.HasOwnerPermissions && !document.SecuritySettings.PermitExtractContent) { errorOutput.DisplayError(string.Format(MiscResources.PdfNoPermissionToExtractContent, Path.GetFileName(filePath))); source.Done(); } var pages = importParams.Slice.Indices(document.PageCount) .Select(index => document.Pages[index]) .TakeWhile(page => { progressCallback(i++, document.PageCount); return(!cancelToken.IsCancellationRequested); }); if (document.Info.Creator != MiscResources.NAPS2 && document.Info.Author != MiscResources.NAPS2) { pdfRenderer.ThrowIfCantRender(); foreach (var page in pages) { source.Put(await ExportRawPdfPage(page, importParams)); } } else { foreach (var page in pages) { await GetImagesFromPage(page, importParams, source); } } } catch (ImageRenderException e) { errorOutput.DisplayError(string.Format(MiscResources.ImportErrorNAPS2Pdf, Path.GetFileName(filePath))); Log.ErrorException("Error importing PDF file.", e); } catch (Exception e) { if (!aborted) { errorOutput.DisplayError(string.Format(MiscResources.ImportErrorCouldNot, Path.GetFileName(filePath))); Log.ErrorException("Error importing PDF file.", e); } } finally { source.Done(); } }, TaskCreationOptions.LongRunning); return(source); }