diff --git a/NAPS2.sln.DotSettings b/NAPS2.sln.DotSettings index ddc9cb6f2..0b95e5bc4 100644 --- a/NAPS2.sln.DotSettings +++ b/NAPS2.sln.DotSettings @@ -1,4 +1,5 @@  + <Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /> <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> <data><IncludeFilters /><ExcludeFilters /></data> diff --git a/NAPS2/FEditScanSettings.cs b/NAPS2/FEditScanSettings.cs index 35bb64236..aa46d97f5 100644 --- a/NAPS2/FEditScanSettings.cs +++ b/NAPS2/FEditScanSettings.cs @@ -27,11 +27,14 @@ using NAPS2.Scan.Exceptions; using NAPS2.Scan.Twain; using NAPS2.Scan.Wia; using Ninject; +using NLog; namespace NAPS2 { public partial class FEditScanSettings : Form { + private readonly Logger logger; + private ScanDevice currentDevice; private int iconID; @@ -39,8 +42,9 @@ namespace NAPS2 private bool suppressChangeEvent; - public FEditScanSettings() + public FEditScanSettings(Logger logger) { + this.logger = logger; InitializeComponent(); AddEnumItems(cmbAlign); AddEnumItems(cmbDepth); @@ -119,6 +123,10 @@ namespace NAPS2 } catch (ScanDriverException e) { + if (e is ScanDriverUnknownException) + { + logger.ErrorException(e.Message, e.InnerException); + } MessageBox.Show(e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } diff --git a/NAPS2/KernelManager.cs b/NAPS2/KernelManager.cs index 2b169e51e..0ff892a1f 100644 --- a/NAPS2/KernelManager.cs +++ b/NAPS2/KernelManager.cs @@ -20,6 +20,7 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using NAPS2.Email; using NAPS2.Pdf; @@ -28,8 +29,11 @@ using NAPS2.Scan.Stub; using NAPS2.Scan.Twain; using NAPS2.Scan.Wia; using Ninject; +using Ninject.Activation; using Ninject.Modules; using NLog; +using NLog.Config; +using NLog.Targets; namespace NAPS2 { @@ -50,7 +54,7 @@ namespace NAPS2 Bind().To().InSingletonScope(); Bind().To(); Bind().To(); - Bind().ToConstant(LogManager.GetLogger("NAPS2")); + Bind().ToMethod(GetLogger).InSingletonScope(); #if DEBUG && false Bind().To().Named(WiaScanDriver.DRIVER_NAME); Bind().To().Named(TwainScanDriver.DRIVER_NAME); @@ -59,6 +63,21 @@ namespace NAPS2 Bind().To().Named(TwainScanDriver.DRIVER_NAME); #endif } + + private Logger GetLogger(IContext arg) + { + var config = new LoggingConfiguration(); + var target = new FileTarget + { + FileName = Path.Combine(Paths.AppData, "errorlog.txt"), + Layout = "${longdate} ${message} ${exception:format=tostring}" + }; + config.AddTarget("errorlogfile", target); + var rule = new LoggingRule("*", LogLevel.Debug, target); + config.LoggingRules.Add(rule); + LogManager.Configuration = config; + return LogManager.GetLogger("NAPS2"); + } } } } diff --git a/NAPS2/Program.cs b/NAPS2/Program.cs index 66e455785..6dc26d728 100644 --- a/NAPS2/Program.cs +++ b/NAPS2/Program.cs @@ -21,9 +21,11 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Windows.Forms; using Ninject; using Ninject.Parameters; +using NLog; namespace NAPS2 { @@ -38,7 +40,14 @@ namespace NAPS2 Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); + Application.ThreadException += UnhandledException; + Application.Run(KernelManager.Kernel.Get()); } + + private static void UnhandledException(object sender, ThreadExceptionEventArgs threadExceptionEventArgs) + { + KernelManager.Kernel.Get().FatalException("An error occurred that caused the application to close.", threadExceptionEventArgs.Exception); + } } } diff --git a/NAPS2/Scan/Exceptions/ScanDriverUnknownException.cs b/NAPS2/Scan/Exceptions/ScanDriverUnknownException.cs index 8a2fd6ba3..d53caf3bf 100644 --- a/NAPS2/Scan/Exceptions/ScanDriverUnknownException.cs +++ b/NAPS2/Scan/Exceptions/ScanDriverUnknownException.cs @@ -28,16 +28,6 @@ namespace NAPS2.Scan.Exceptions { private const string DEFAULT_MESSAGE = "An error occured with the scanning driver."; - public ScanDriverUnknownException() - : base(DEFAULT_MESSAGE) - { - } - - public ScanDriverUnknownException(string message) - : base(message) - { - } - public ScanDriverUnknownException(Exception innerException) : base(DEFAULT_MESSAGE, innerException) { diff --git a/NAPS2/Scan/Twain/TwainApi.cs b/NAPS2/Scan/Twain/TwainApi.cs index ae965a1af..2c0eff5a8 100644 --- a/NAPS2/Scan/Twain/TwainApi.cs +++ b/NAPS2/Scan/Twain/TwainApi.cs @@ -49,24 +49,13 @@ namespace NAPS2.Scan.Twain public static string SelectDeviceUI() { - try + var tw = new Twain(); + if (!tw.Init(Application.OpenForms[0].Handle)) { - var tw = new Twain(); - if (!tw.Init(Application.OpenForms[0].Handle)) - { - throw new NoDevicesFoundException(); - } - tw.Select(); - return tw.GetCurrentName(); - } - catch (ScanDriverException) - { - throw; - } - catch (Exception e) - { - throw new ScanDriverUnknownException(e); + throw new NoDevicesFoundException(); } + tw.Select(); + return tw.GetCurrentName(); } public List Scan() diff --git a/NAPS2/Scan/Twain/TwainScanDriver.cs b/NAPS2/Scan/Twain/TwainScanDriver.cs index 9b50dc65d..957977b6c 100644 --- a/NAPS2/Scan/Twain/TwainScanDriver.cs +++ b/NAPS2/Scan/Twain/TwainScanDriver.cs @@ -22,6 +22,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; +using NAPS2.Scan.Exceptions; namespace NAPS2.Scan.Twain { @@ -44,9 +45,20 @@ namespace NAPS2.Scan.Twain { throw new InvalidOperationException("IScanDriver.DialogParent must be specified before calling PromptForDevice()."); } - string deviceId = TwainApi.SelectDeviceUI(); - string deviceName = deviceId; - return new ScanDevice(deviceId, deviceName, DRIVER_NAME); + try + { + string deviceId = TwainApi.SelectDeviceUI(); + string deviceName = deviceId; + return new ScanDevice(deviceId, deviceName, DRIVER_NAME); + } + catch (ScanDriverException) + { + throw; + } + catch (Exception e) + { + throw new ScanDriverUnknownException(e); + } } public IEnumerable Scan() @@ -59,8 +71,19 @@ namespace NAPS2.Scan.Twain { throw new InvalidOperationException("IScanDriver.DialogParent must be specified before calling Scan()."); } - var api = new TwainApi(ScanSettings, DialogParent); - return api.Scan(); + try + { + var api = new TwainApi(ScanSettings, DialogParent); + return api.Scan(); + } + catch (ScanDriverException) + { + throw; + } + catch (Exception e) + { + throw new ScanDriverUnknownException(e); + } } } } diff --git a/NAPS2/Scan/Wia/WiaApi.cs b/NAPS2/Scan/Wia/WiaApi.cs index 5a9dc1af1..dfd0c42b4 100644 --- a/NAPS2/Scan/Wia/WiaApi.cs +++ b/NAPS2/Scan/Wia/WiaApi.cs @@ -342,11 +342,12 @@ namespace NAPS2.Scan.Wia { try { - items = wiaCommonDialog.ShowSelectItems(device, WiaImageIntent.UnspecifiedIntent, WiaImageBias.MaximizeQuality, true, true, true); + items = wiaCommonDialog.ShowSelectItems(device, WiaImageIntent.UnspecifiedIntent, + WiaImageBias.MaximizeQuality, true, true, true); } catch (COMException e) { - if ((uint)e.ErrorCode == UI_CANCELED) + if ((uint) e.ErrorCode == UI_CANCELED) return null; } } @@ -355,14 +356,15 @@ namespace NAPS2.Scan.Wia SetupDevice(); SetupItem(items[1]); } - var file = (ImageFile)wiaCommonDialog.ShowTransfer(items[1], "{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}", false); + var file = + (ImageFile) wiaCommonDialog.ShowTransfer(items[1], "{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}", false); if (file == null) { // User cancelled return null; } - using (var stream = new MemoryStream((byte[])file.FileData.get_BinaryData())) + using (var stream = new MemoryStream((byte[]) file.FileData.get_BinaryData())) { using (Image output = Image.FromStream(stream)) { @@ -388,19 +390,19 @@ namespace NAPS2.Scan.Wia } } - double realWidth = output.Width / koef; - double realHeight = output.Height / koef; + double realWidth = output.Width/koef; + double realHeight = output.Height/koef; - double horizontalRes = output.HorizontalResolution / koef; - double verticalRes = output.VerticalResolution / koef; + double horizontalRes = output.HorizontalResolution/koef; + double verticalRes = output.VerticalResolution/koef; - using (var result = new Bitmap((int)realWidth, (int)realHeight)) + using (var result = new Bitmap((int) realWidth, (int) realHeight)) using (Graphics g = Graphics.FromImage(result)) { g.InterpolationMode = InterpolationMode.HighQualityBicubic; - g.DrawImage(output, 0, 0, (int)realWidth, (int)realHeight); + g.DrawImage(output, 0, 0, (int) realWidth, (int) realHeight); - result.SetResolution((float)horizontalRes, (float)verticalRes); + result.SetResolution((float) horizontalRes, (float) verticalRes); ScanBitDepth bitDepth = settingsExt != null ? settingsExt.BitDepth : ScanBitDepth.C24Bit; ImageFormat imageFormat = settings.MaxQuality ? ImageFormat.Png : ImageFormat.Jpeg; @@ -411,11 +413,11 @@ namespace NAPS2.Scan.Wia } catch (COMException e) { - if ((uint)e.ErrorCode == ERROR_OUT_OF_PAPER) + if ((uint) e.ErrorCode == ERROR_OUT_OF_PAPER) { return null; } - else if ((uint)e.ErrorCode == ERROR_OFFLINE) + else if ((uint) e.ErrorCode == ERROR_OFFLINE) { throw new DeviceOfflineException(); } diff --git a/NAPS2/Scan/Wia/WiaScanDriver.cs b/NAPS2/Scan/Wia/WiaScanDriver.cs index 95f0be726..88b9f1955 100644 --- a/NAPS2/Scan/Wia/WiaScanDriver.cs +++ b/NAPS2/Scan/Wia/WiaScanDriver.cs @@ -22,6 +22,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; +using NAPS2.Scan.Exceptions; namespace NAPS2.Scan.Wia { @@ -44,7 +45,18 @@ namespace NAPS2.Scan.Wia { throw new InvalidOperationException("IScanDriver.DialogParent must be specified before calling PromptForDevice()."); } - return WiaApi.SelectDeviceUI(); + try + { + return WiaApi.SelectDeviceUI(); + } + catch (ScanDriverException) + { + throw; + } + catch (Exception e) + { + throw new ScanDriverUnknownException(e); + } } public IEnumerable Scan() @@ -58,10 +70,34 @@ namespace NAPS2.Scan.Wia throw new InvalidOperationException("IScanDriver.DialogParent must be specified before calling Scan()."); } var result = new List(); - var api = new WiaApi(ScanSettings); + WiaApi api; + try + { + api = new WiaApi(ScanSettings); + } + catch (ScanDriverException) + { + throw; + } + catch (Exception e) + { + throw new ScanDriverUnknownException(e); + } while (true) { - ScannedImage image = api.GetImage(); + ScannedImage image; + try + { + image = api.GetImage(); + } + catch (ScanDriverException) + { + throw; + } + catch (Exception e) + { + throw new ScanDriverUnknownException(e); + } if (image == null) { break; diff --git a/NAPS2/ScanPerformer.cs b/NAPS2/ScanPerformer.cs index 6814cf715..bab5b7343 100644 --- a/NAPS2/ScanPerformer.cs +++ b/NAPS2/ScanPerformer.cs @@ -25,16 +25,19 @@ using System.Windows.Forms; using NAPS2.Scan; using NAPS2.Scan.Exceptions; using Ninject; +using NLog; namespace NAPS2 { public class ScanPerformer : IScanPerformer { private readonly IKernel kernel; + private readonly Logger logger; - public ScanPerformer(IKernel kernel) + public ScanPerformer(IKernel kernel, Logger logger) { this.kernel = kernel; + this.logger = logger; } public void PerformScan(ScanSettings scanSettings, IWin32Window dialogParent, IScanReceiver scanReceiver) @@ -53,6 +56,10 @@ namespace NAPS2 } catch (ScanDriverException e) { + if (e is ScanDriverUnknownException) + { + logger.ErrorException(e.Message, e.InnerException); + } MessageBox.Show(e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }