From 0ce7d132b23b5bcf736405c754e2caa4541d733e Mon Sep 17 00:00:00 2001 From: Mikhail Shcherbakov Date: Mon, 29 Jan 2018 00:48:15 +0300 Subject: [PATCH 01/17] Add Outtake Form. --- AutoPrintr/AutoPrintr.Core/Models/Document.cs | 2 ++ AutoPrintr/AutoPrintr.Core/Models/DocumentSize.cs | 3 ++- AutoPrintr/AutoPrintr.Core/Models/DocumentType.cs | 3 ++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/AutoPrintr/AutoPrintr.Core/Models/Document.cs b/AutoPrintr/AutoPrintr.Core/Models/Document.cs index 503153d..ada1360 100644 --- a/AutoPrintr/AutoPrintr.Core/Models/Document.cs +++ b/AutoPrintr/AutoPrintr.Core/Models/Document.cs @@ -41,6 +41,7 @@ public static string GetTypeTitle(DocumentType type) case DocumentType.Estimate: return "Estimate"; case DocumentType.Ticket: return "Ticket"; case DocumentType.IntakeForm: return "Intake Form"; + case DocumentType.OuttakeForm: return "Outtake Form"; case DocumentType.Receipt: return "Receipt"; case DocumentType.ZReport: return "Z Report"; case DocumentType.TicketReceipt: return "Ticket Receipt"; @@ -61,6 +62,7 @@ public static string GetSizeTitle(DocumentSize type) case DocumentSize.Label: return "Size: 1.1x3"; case DocumentSize.Receipt: return "Size: 80mm"; case DocumentSize.IntakeForm: return "Intake Form"; + case DocumentSize.OuttakeForm: return "Outtake Form"; case DocumentSize.PopDrawer: return "Pop Drawer"; default: return null; } diff --git a/AutoPrintr/AutoPrintr.Core/Models/DocumentSize.cs b/AutoPrintr/AutoPrintr.Core/Models/DocumentSize.cs index d0bdcb2..27660ab 100644 --- a/AutoPrintr/AutoPrintr.Core/Models/DocumentSize.cs +++ b/AutoPrintr/AutoPrintr.Core/Models/DocumentSize.cs @@ -6,6 +6,7 @@ public enum DocumentSize : byte Label, Receipt, IntakeForm, - PopDrawer + PopDrawer, + OuttakeForm } } \ No newline at end of file diff --git a/AutoPrintr/AutoPrintr.Core/Models/DocumentType.cs b/AutoPrintr/AutoPrintr.Core/Models/DocumentType.cs index 7e0e41b..1b15476 100644 --- a/AutoPrintr/AutoPrintr.Core/Models/DocumentType.cs +++ b/AutoPrintr/AutoPrintr.Core/Models/DocumentType.cs @@ -13,6 +13,7 @@ public enum DocumentType : byte Adjustment, CustomerID, Asset, - TicketLabel + TicketLabel, + OuttakeForm } } \ No newline at end of file From f32cd6d64bd446df472bc5c6f71d078223365b85 Mon Sep 17 00:00:00 2001 From: Mikhail Shcherbakov Date: Mon, 29 Jan 2018 02:34:39 +0300 Subject: [PATCH 02/17] Fix the duplicate icon issue. --- AutoPrintr/AutoPrintr/App.xaml.cs | 18 +++ AutoPrintr/AutoPrintr/AutoPrintr.csproj | 1 + .../AutoPrintr/Helpers/SystemTrayUpdater.cs | 114 ++++++++++++++++++ AutoPrintr/AutoPrintr/Helpers/WpfApp.cs | 1 + 4 files changed, 134 insertions(+) create mode 100644 AutoPrintr/AutoPrintr/Helpers/SystemTrayUpdater.cs diff --git a/AutoPrintr/AutoPrintr/App.xaml.cs b/AutoPrintr/AutoPrintr/App.xaml.cs index 9b76560..81d9490 100644 --- a/AutoPrintr/AutoPrintr/App.xaml.cs +++ b/AutoPrintr/AutoPrintr/App.xaml.cs @@ -51,6 +51,10 @@ protected override async void OnStartup(StartupEventArgs e) { trayIcon.ShowBalloonTip(); } + else + { + RefreshTrayArea(); + } } protected override async void OnExit(ExitEventArgs e) @@ -70,6 +74,20 @@ private bool CheckIsNet45Installed() return netVersion >= 378389; } } + + private static void RefreshTrayArea() + { + ILoggerService logger = null; + try + { + logger = SimpleIoc.Default.GetInstance(); + Task.Run(() => SystemTrayUpdater.Refresh(logger)); + } + catch (Exception e) + { + logger?.WriteError($"Error refresh tray area. {e}"); + } + } #endregion #region Exceptions diff --git a/AutoPrintr/AutoPrintr/AutoPrintr.csproj b/AutoPrintr/AutoPrintr/AutoPrintr.csproj index b273ca8..0485e82 100644 --- a/AutoPrintr/AutoPrintr/AutoPrintr.csproj +++ b/AutoPrintr/AutoPrintr/AutoPrintr.csproj @@ -147,6 +147,7 @@ + diff --git a/AutoPrintr/AutoPrintr/Helpers/SystemTrayUpdater.cs b/AutoPrintr/AutoPrintr/Helpers/SystemTrayUpdater.cs new file mode 100644 index 0000000..2c060a9 --- /dev/null +++ b/AutoPrintr/AutoPrintr/Helpers/SystemTrayUpdater.cs @@ -0,0 +1,114 @@ +using System; +using System.Runtime.InteropServices; +using AutoPrintr.Core.IServices; + +namespace AutoPrintr.Helpers +{ + public class SystemTrayUpdater + { + // ReSharper disable once InconsistentNaming + [StructLayout(LayoutKind.Sequential)] + private struct RECT + { + public int left; + public int top; + public int right; + public int bottom; + } + + [DllImport("user32.dll")] + private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); + + [DllImport("user32.dll")] + private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); + + [DllImport("user32.dll")] + private static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect); + + [DllImport("user32.dll")] + private static extern IntPtr SendMessage(IntPtr hWnd, uint msg, int wParam, int lParam); + + public static void Refresh(ILoggerService logger) + { + RefreshNotificationArea(logger); + RefreshOverflowNotificationArea(logger); + } + + private static void RefreshNotificationArea(ILoggerService logger) + { + try + { + var systemTrayContainerHandle = FindWindow("Shell_TrayWnd", null); + if (systemTrayContainerHandle == IntPtr.Zero) + { + logger?.WriteError("Not found Shell_TrayWnd in SystemTray Updater."); + return; + } + + var systemTrayHandle = FindWindowEx(systemTrayContainerHandle, IntPtr.Zero, "TrayNotifyWnd", null); + if (systemTrayHandle == IntPtr.Zero) + { + logger?.WriteError("Not found TrayNotifyWnd in SystemTray Updater."); + return; + } + + var sysPagerHandle = FindWindowEx(systemTrayHandle, IntPtr.Zero, "SysPager", null); + if (sysPagerHandle == IntPtr.Zero) + { + logger?.WriteError("Not found SysPager in SystemTray Updater."); + return; + } + + var notificationAreaHandle = FindWindowEx(sysPagerHandle, IntPtr.Zero, "ToolbarWindow32", null); + if (notificationAreaHandle == IntPtr.Zero) + { + logger?.WriteError("Not found ToolbarWindow32 of SysPager in SystemTray Updater."); + return; + } + + logger?.WriteInformation("Refresh the notification area."); + RefreshTrayArea(notificationAreaHandle); + } + catch (Exception e) + { + logger?.WriteError($"Error refresh the notification area. {e}"); + } + } + + private static void RefreshOverflowNotificationArea(ILoggerService logger) + { + try + { + var notifyIconOverflowWindowHandle = FindWindow("NotifyIconOverflowWindow", null); + if (notifyIconOverflowWindowHandle == IntPtr.Zero) + { + logger?.WriteError("Not found NotifyIconOverflowWindow in SystemTray Updater."); + return; + } + + var overflowNotificationAreaHandle = FindWindowEx(notifyIconOverflowWindowHandle, IntPtr.Zero, "ToolbarWindow32", null); + if (overflowNotificationAreaHandle == IntPtr.Zero) + { + logger?.WriteError("Not found ToolbarWindow32 of NotifyIconOverflowWindow in SystemTray Updater."); + return; + } + + logger?.WriteInformation("Refresh the overflow notification area."); + RefreshTrayArea(overflowNotificationAreaHandle); + } + catch (Exception e) + { + logger?.WriteError($"Error refresh the overflow notification area. {e}"); + } + } + + private static void RefreshTrayArea(IntPtr windowHandle) + { + const uint wmMousemove = 0x0200; + GetClientRect(windowHandle, out var rect); + for (var x = rect.left; x < rect.right; x += 5) + for (var y = rect.top; y < rect.bottom; y += 5) + SendMessage(windowHandle, wmMousemove, 0, (y << 16) + x); + } + } +} \ No newline at end of file diff --git a/AutoPrintr/AutoPrintr/Helpers/WpfApp.cs b/AutoPrintr/AutoPrintr/Helpers/WpfApp.cs index b0f5207..566c139 100644 --- a/AutoPrintr/AutoPrintr/Helpers/WpfApp.cs +++ b/AutoPrintr/AutoPrintr/Helpers/WpfApp.cs @@ -58,6 +58,7 @@ public override async Task Startup(string[] args) continue; process.Kill(); + process.Dispose(); } } From c343e3c8609a2422f145d5f87f6d3e97a57626d8 Mon Sep 17 00:00:00 2001 From: Mikhail Shcherbakov Date: Mon, 29 Jan 2018 02:36:13 +0300 Subject: [PATCH 03/17] Change a version to 2.0.22 --- AutoPrintr/AssemblyVersion.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AutoPrintr/AssemblyVersion.cs b/AutoPrintr/AssemblyVersion.cs index b9181f2..a4d57b8 100644 --- a/AutoPrintr/AssemblyVersion.cs +++ b/AutoPrintr/AssemblyVersion.cs @@ -18,5 +18,5 @@ // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("2.0.21.0")] -[assembly: AssemblyFileVersion("2.0.21.0")] +[assembly: AssemblyVersion("2.0.22.0")] +[assembly: AssemblyFileVersion("2.0.22.0")] From 91b8f84dcbf813c920f4afd81d5d281a4c3967f5 Mon Sep 17 00:00:00 2001 From: Mikhail Shcherbakov Date: Mon, 29 Jan 2018 15:39:10 +0300 Subject: [PATCH 04/17] Refresh a tray area by every start. --- AutoPrintr/AutoPrintr/App.xaml.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/AutoPrintr/AutoPrintr/App.xaml.cs b/AutoPrintr/AutoPrintr/App.xaml.cs index 81d9490..4d29485 100644 --- a/AutoPrintr/AutoPrintr/App.xaml.cs +++ b/AutoPrintr/AutoPrintr/App.xaml.cs @@ -51,10 +51,8 @@ protected override async void OnStartup(StartupEventArgs e) { trayIcon.ShowBalloonTip(); } - else - { - RefreshTrayArea(); - } + + RefreshTrayArea(); } protected override async void OnExit(ExitEventArgs e) From 3eb99e6a5570196b50fbe89b09f702d600d4a710 Mon Sep 17 00:00:00 2001 From: Mikhail Shcherbakov Date: Fri, 2 Feb 2018 01:09:01 +0300 Subject: [PATCH 05/17] Add Debug mode for the service. --- AutoPrintr/AutoPrintr.Service/Helpers/Commands.cs | 3 ++- AutoPrintr/AutoPrintr.Service/Service.cs | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/AutoPrintr/AutoPrintr.Service/Helpers/Commands.cs b/AutoPrintr/AutoPrintr.Service/Helpers/Commands.cs index 556fdf3..766158b 100644 --- a/AutoPrintr/AutoPrintr.Service/Helpers/Commands.cs +++ b/AutoPrintr/AutoPrintr.Service/Helpers/Commands.cs @@ -5,6 +5,7 @@ internal enum Commands Install, Uninstall, Start, - Stop + Stop, + Debug } } \ No newline at end of file diff --git a/AutoPrintr/AutoPrintr.Service/Service.cs b/AutoPrintr/AutoPrintr.Service/Service.cs index 37d3f68..62f6519 100644 --- a/AutoPrintr/AutoPrintr.Service/Service.cs +++ b/AutoPrintr/AutoPrintr.Service/Service.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Reflection; using System.ServiceProcess; +using System.Threading; namespace AutoPrintr.Service { @@ -108,6 +109,11 @@ private static void RunCommand(Commands command) if (ServiceController.GetServices().Any(x => x.ServiceName == SERVICE_NAME)) ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location }); break; + case Commands.Debug: + var service = new Service(); + service.OnStart(new string[0]); + Thread.Sleep(Timeout.Infinite); + break; } } #endregion From 66bcce55adf2d7a902ef75915b32adb37a1bca08 Mon Sep 17 00:00:00 2001 From: Mikhail Shcherbakov Date: Fri, 2 Feb 2018 01:19:26 +0300 Subject: [PATCH 06/17] Fix a typo in a parameter ordering. --- AutoPrintr/AutoPrintr/Helpers/WindowsServiceClient.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AutoPrintr/AutoPrintr/Helpers/WindowsServiceClient.cs b/AutoPrintr/AutoPrintr/Helpers/WindowsServiceClient.cs index b563457..9cc49de 100644 --- a/AutoPrintr/AutoPrintr/Helpers/WindowsServiceClient.cs +++ b/AutoPrintr/AutoPrintr/Helpers/WindowsServiceClient.cs @@ -57,7 +57,7 @@ public async Task ConnectAsync(Action connectionFailed) _cts = new CancellationTokenSource(); _task = Task.Run( - async () => await PingByTimeout(service => service.Connect(), service => service.Ping(), _cts.Token), + async () => await PingByTimeout(service => service.Ping(), service => service.Connect(), _cts.Token), _cts.Token); return result; From c0dbf9b8dc10920fa20050d28f114de00bc39860 Mon Sep 17 00:00:00 2001 From: Mikhail Shcherbakov Date: Fri, 2 Feb 2018 01:42:57 +0300 Subject: [PATCH 07/17] Improve the stopping service. --- AutoPrintr/AutoPrintr.Service/Service.cs | 91 ++++++++++++++++-------- 1 file changed, 61 insertions(+), 30 deletions(-) diff --git a/AutoPrintr/AutoPrintr.Service/Service.cs b/AutoPrintr/AutoPrintr.Service/Service.cs index 62f6519..1f279ef 100644 --- a/AutoPrintr/AutoPrintr.Service/Service.cs +++ b/AutoPrintr/AutoPrintr.Service/Service.cs @@ -4,6 +4,7 @@ using System; using System.Configuration.Install; using System.Diagnostics; +using System.IO; using System.Linq; using System.Reflection; using System.ServiceProcess; @@ -79,41 +80,71 @@ private static void CurrentDomain_UnhandledException(object sender, UnhandledExc private static void RunCommand(Commands command) { - switch (command) + try { - case Commands.Install: - if (!ServiceController.GetServices().Any(x => x.ServiceName == SERVICE_NAME)) - ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location }); - break; - case Commands.Start: - using (ServiceController sc = new ServiceController(SERVICE_NAME)) - { - if (ServiceController.GetServices().Any(x => x.ServiceName == SERVICE_NAME)) + switch (command) + { + case Commands.Install: + if (!ServiceController.GetServices().Any(x => x.ServiceName == SERVICE_NAME)) + ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location }); + break; + case Commands.Start: + using (ServiceController sc = new ServiceController(SERVICE_NAME)) { - if (sc.Status != ServiceControllerStatus.Running) - sc.Start(); + if (ServiceController.GetServices().Any(x => x.ServiceName == SERVICE_NAME)) + { + if (sc.Status != ServiceControllerStatus.Running) + sc.Start(); + } } - } - break; - case Commands.Stop: - using (var sc = new ServiceController(SERVICE_NAME)) - { - if (ServiceController.GetServices().Any(x => x.ServiceName == SERVICE_NAME)) + + break; + case Commands.Stop: + using (var sc = new ServiceController(SERVICE_NAME)) { - if (sc.Status != ServiceControllerStatus.Stopped) - sc.Stop(); + if (ServiceController.GetServices().Any(x => x.ServiceName == SERVICE_NAME)) + { + if (sc.Status != ServiceControllerStatus.Stopped) + { + sc.Stop(); + } + + try + { + sc.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromMinutes(1)); + } + catch (System.ServiceProcess.TimeoutException) + { + foreach (var process in Process.GetProcessesByName(Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().Location))) + { + if (process.Id == 0 || + process.Id == Process.GetCurrentProcess().Id) + { + continue; + } + + process.Kill(); + process.WaitForExit(60 * 1000); + } + } + } } - } - break; - case Commands.Uninstall: - if (ServiceController.GetServices().Any(x => x.ServiceName == SERVICE_NAME)) - ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location }); - break; - case Commands.Debug: - var service = new Service(); - service.OnStart(new string[0]); - Thread.Sleep(Timeout.Infinite); - break; + + break; + case Commands.Uninstall: + if (ServiceController.GetServices().Any(x => x.ServiceName == SERVICE_NAME)) + ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location }); + break; + case Commands.Debug: + var service = new Service(); + service.OnStart(new string[0]); + Thread.Sleep(Timeout.Infinite); + break; + } + } + catch (Exception exception) + { + // ignore errors } } #endregion From 620ae7df799eeed45b78f34a1b74061dd995cd80 Mon Sep 17 00:00:00 2001 From: Mikhail Shcherbakov Date: Fri, 2 Feb 2018 01:43:27 +0300 Subject: [PATCH 08/17] Change a version to 2.0.22. --- AutoPrintr/AssemblyVersion.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AutoPrintr/AssemblyVersion.cs b/AutoPrintr/AssemblyVersion.cs index b9181f2..a4d57b8 100644 --- a/AutoPrintr/AssemblyVersion.cs +++ b/AutoPrintr/AssemblyVersion.cs @@ -18,5 +18,5 @@ // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("2.0.21.0")] -[assembly: AssemblyFileVersion("2.0.21.0")] +[assembly: AssemblyVersion("2.0.22.0")] +[assembly: AssemblyFileVersion("2.0.22.0")] From ca31a3867a5b64e7e5fcaad7f16ee65026dc1f80 Mon Sep 17 00:00:00 2001 From: Mikhail Shcherbakov Date: Fri, 2 Feb 2018 02:50:02 +0300 Subject: [PATCH 09/17] Fix getting printers from the service. --- .../Services/PrinterService.cs | 24 ++++++++++++------- .../Helpers/WindowsServiceClient.cs | 4 ++-- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/AutoPrintr/AutoPrintr.Service/Services/PrinterService.cs b/AutoPrintr/AutoPrintr.Service/Services/PrinterService.cs index a5be05c..385f33a 100644 --- a/AutoPrintr/AutoPrintr.Service/Services/PrinterService.cs +++ b/AutoPrintr/AutoPrintr.Service/Services/PrinterService.cs @@ -33,17 +33,25 @@ public PrinterService(ISettingsService settingsService, #region Methods public IEnumerable GetPrinters() { - var printers = GetInstalledPrinters(); + try + { + var printers = GetInstalledPrinters(); + + var result = new List(); + foreach (var printer in printers) + { + var existing = _settingsService.Settings.Printers.SingleOrDefault(x => string.Compare(x.Name, printer.Name, true) == 0); + var existingCopy = existing?.Clone() as Printer; + result.Add(existingCopy ?? printer); + } - var result = new List(); - foreach (var printer in printers) + return result; + } + catch (Exception e) { - var existing = _settingsService.Settings.Printers.SingleOrDefault(x => string.Compare(x.Name, printer.Name, true) == 0); - var existingCopy = existing?.Clone() as Printer; - result.Add(existingCopy ?? printer); + _loggingService.WriteError($"Error getting printers: {e}"); + return null; } - - return result; } public async Task PrintDocumentAsync(Printer printer, Document document, int count, Action completed = null) diff --git a/AutoPrintr/AutoPrintr/Helpers/WindowsServiceClient.cs b/AutoPrintr/AutoPrintr/Helpers/WindowsServiceClient.cs index 9cc49de..f77d85d 100644 --- a/AutoPrintr/AutoPrintr/Helpers/WindowsServiceClient.cs +++ b/AutoPrintr/AutoPrintr/Helpers/WindowsServiceClient.cs @@ -81,11 +81,11 @@ public async Task DisconnectAsync() } } - public Task> GetPrintersAsync() + public async Task> GetPrintersAsync() { try { - return TryCall(service => service.GetPrinters()); + return await TryCall(service => service.GetPrinters()); } catch (Exception ex) { From 51bcc1da4ffc1685286f4c1fbc356c742884bc8b Mon Sep 17 00:00:00 2001 From: Mikhail Shcherbakov Date: Fri, 2 Feb 2018 02:56:38 +0300 Subject: [PATCH 10/17] Improve WCF reconnection. --- .../AutoPrintr/Helpers/ReliableService.cs | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/AutoPrintr/AutoPrintr/Helpers/ReliableService.cs b/AutoPrintr/AutoPrintr/Helpers/ReliableService.cs index b12db86..5826653 100644 --- a/AutoPrintr/AutoPrintr/Helpers/ReliableService.cs +++ b/AutoPrintr/AutoPrintr/Helpers/ReliableService.cs @@ -7,16 +7,13 @@ namespace AutoPrintr.Helpers { public abstract class ReliableService : IDisposable where T: class { - private readonly int _timeoutStep; - private readonly int _timeoutPing; + private readonly int _timeout; private ChannelFactory _factory; private T _channel; - protected ReliableService(int timeoutStepInMilliseconds = 100, - int timeoutPingInMilliseconds = 2000) + protected ReliableService(int timeoutPingInMilliseconds = 2000) { - _timeoutStep = timeoutStepInMilliseconds; - _timeoutPing = timeoutPingInMilliseconds; + _timeout = timeoutPingInMilliseconds; } protected void InitializeFactory(ChannelFactory newFactory) @@ -26,7 +23,7 @@ protected void InitializeFactory(ChannelFactory newFactory) protected void Connect(Action subscribe) { - _channel = _factory.CreateChannel(); + _channel = _factory?.CreateChannel(); subscribe(_channel); } @@ -52,7 +49,7 @@ protected async Task PingByTimeout(Action ping, Action subscribe, Cancella _channel = null; } - await Task.Delay(_timeoutPing, token); + await Task.Delay(_timeout, token); } } catch (TaskCanceledException) @@ -76,22 +73,23 @@ protected TResult TryCall(Func lambda) { try { - if (_channel == null) + if (_channel != null) { - _channel = _factory?.CreateChannel() ?? throw new Exception($"ReliableService of {typeof(T)} is disposed."); + return lambda(_channel); } - - return lambda(_channel); } - catch (Exception e) + catch (Exception) { if (attempt >= 3) throw; + } - _channel = null; + if (attempt >= 3) + { + throw new Exception("The WCF channel is not initialized."); } - Thread.Sleep(attempt * _timeoutStep); + Thread.Sleep(_timeout); attempt++; } } From 3ce116ac88d4d9b8f23afc4dadf35f25d7a7bc8c Mon Sep 17 00:00:00 2001 From: Mikhail Shcherbakov Date: Fri, 2 Feb 2018 15:57:05 +0300 Subject: [PATCH 11/17] Improve WCF disconnection. --- .../IServices/IWindowsService.cs | 7 +- .../Models/DocumentTypeSettings.cs | 9 ++- .../AutoPrintr.Service/WindowsService.cs | 70 ++++++++----------- .../Helpers/WindowsServiceClient.cs | 7 +- AutoPrintr/AutoPrintr/Helpers/WpfApp.cs | 8 +-- 5 files changed, 48 insertions(+), 53 deletions(-) diff --git a/AutoPrintr/AutoPrintr.Core/IServices/IWindowsService.cs b/AutoPrintr/AutoPrintr.Core/IServices/IWindowsService.cs index 1eade45..1c5558c 100644 --- a/AutoPrintr/AutoPrintr.Core/IServices/IWindowsService.cs +++ b/AutoPrintr/AutoPrintr.Core/IServices/IWindowsService.cs @@ -1,4 +1,5 @@ -using AutoPrintr.Core.Models; +using System; +using AutoPrintr.Core.Models; using System.Collections.Generic; using System.ServiceModel; using System.Threading.Tasks; @@ -9,10 +10,10 @@ namespace AutoPrintr.Core.IServices public interface IWindowsService { [OperationContract] - void Connect(); + void Connect(Guid id); [OperationContract] - void Disconnect(); + void Disconnect(Guid id); [OperationContract] void Ping(); diff --git a/AutoPrintr/AutoPrintr.Core/Models/DocumentTypeSettings.cs b/AutoPrintr/AutoPrintr.Core/Models/DocumentTypeSettings.cs index ee194d1..7a2691d 100644 --- a/AutoPrintr/AutoPrintr.Core/Models/DocumentTypeSettings.cs +++ b/AutoPrintr/AutoPrintr.Core/Models/DocumentTypeSettings.cs @@ -1,10 +1,17 @@ -namespace AutoPrintr.Core.Models +using System.Runtime.Serialization; + +namespace AutoPrintr.Core.Models { + [DataContract] public class DocumentTypeSettings : BaseModel { + [DataMember] public bool Enabled { get; set; } + [DataMember] public int Quantity { get; set; } + [DataMember] public bool AutoPrint { get; set; } + [DataMember] public DocumentType DocumentType { get; set; } } } \ No newline at end of file diff --git a/AutoPrintr/AutoPrintr.Service/WindowsService.cs b/AutoPrintr/AutoPrintr.Service/WindowsService.cs index d2f6910..e3be82b 100644 --- a/AutoPrintr/AutoPrintr.Service/WindowsService.cs +++ b/AutoPrintr/AutoPrintr.Service/WindowsService.cs @@ -3,6 +3,7 @@ using AutoPrintr.Service.IServices; using GalaSoft.MvvmLight.Ioc; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.ServiceModel; @@ -14,8 +15,7 @@ namespace AutoPrintr.Service internal class WindowsService : IWindowsService { #region Properties - private readonly List _callbacks = new List(); - private readonly object guardCallbacks = new object(); + private readonly ConcurrentDictionary _callbacks = new ConcurrentDictionary(); private IJobsService JobsService => SimpleIoc.Default.GetInstance(); private IPrinterService PrintersService => SimpleIoc.Default.GetInstance(); @@ -26,33 +26,22 @@ internal class WindowsService : IWindowsService #endregion #region Methods - public void Connect() + public void Connect(Guid id) { + LoggerService.WriteInformation($"Add WCF connection from the '{id}' client."); var callback = OperationContext.Current.GetCallbackChannel(); if (callback == null) { return; } - lock (guardCallbacks) - { - _callbacks.Add(callback); - } + _callbacks.AddOrUpdate(id, callback, (key, value) => callback); } - public void Disconnect() + public void Disconnect(Guid id) { - var callback = OperationContext.Current.GetCallbackChannel(); - if (callback == null) - { - return; - } - - lock (guardCallbacks) - { - if (_callbacks.Contains(callback)) - _callbacks.Remove(callback); - } + LoggerService.WriteInformation($"Remove WCF connection from the '{id}' client."); + _callbacks.TryRemove(id, out _); } public void Ping() @@ -148,31 +137,28 @@ public static void OnConnectionFailed() private void ForEachCallback(Action call, bool store = false) { - lock (guardCallbacks) + foreach (var entry in _callbacks) { - for (int i = _callbacks.Count - 1; i >= 0; i--) + try + { + call(entry.Value); + } + catch (ObjectDisposedException ex) + { + _callbacks.TryRemove(entry.Key, out _); + Debug.WriteLine($"Error in {nameof(WindowsService)}: {ex.Message}"); + LoggerService.WriteWarning($"Error in {nameof(WindowsService)}: {ex.Message}"); + } + catch (CommunicationException ex) + { + _callbacks.TryRemove(entry.Key, out _); + Debug.WriteLine($"Error in {nameof(WindowsService)}: {ex.Message}"); + LoggerService.WriteWarning($"Error in {nameof(WindowsService)}: {ex.Message}"); + } + catch (Exception ex) { - try - { - call(_callbacks[i]); - } - catch (ObjectDisposedException ex) - { - _callbacks.RemoveAt(i); - Debug.WriteLine($"Error in {nameof(WindowsService)}: {ex.Message}"); - LoggerService.WriteWarning($"Error in {nameof(WindowsService)}: {ex.Message}"); - } - catch (CommunicationException ex) - { - _callbacks.RemoveAt(i); - Debug.WriteLine($"Error in {nameof(WindowsService)}: {ex.Message}"); - LoggerService.WriteWarning($"Error in {nameof(WindowsService)}: {ex.Message}"); - } - catch (Exception ex) - { - Debug.WriteLine($"Error in {nameof(WindowsService)}: {ex}"); - LoggerService.WriteError($"Error in {nameof(WindowsService)}: {ex}"); - } + Debug.WriteLine($"Error in {nameof(WindowsService)}: {ex}"); + LoggerService.WriteError($"Error in {nameof(WindowsService)}: {ex}"); } } } diff --git a/AutoPrintr/AutoPrintr/Helpers/WindowsServiceClient.cs b/AutoPrintr/AutoPrintr/Helpers/WindowsServiceClient.cs index f77d85d..9642dee 100644 --- a/AutoPrintr/AutoPrintr/Helpers/WindowsServiceClient.cs +++ b/AutoPrintr/AutoPrintr/Helpers/WindowsServiceClient.cs @@ -14,6 +14,7 @@ namespace AutoPrintr.Helpers internal class WindowsServiceClient : ReliableService, IWindowsServiceCallback, IWindowsServiceClient { #region Properties + private readonly Guid _id = Guid.NewGuid(); private readonly Dispatcher _dispatcher; private readonly ILoggerService _loggerService; private CancellationTokenSource _cts; @@ -47,7 +48,7 @@ public async Task ConnectAsync(Action connectionFailed) bool result; try { - Connect(service => service.Connect()); + Connect(service => service.Connect(_id)); result = true; } catch (Exception) @@ -57,7 +58,7 @@ public async Task ConnectAsync(Action connectionFailed) _cts = new CancellationTokenSource(); _task = Task.Run( - async () => await PingByTimeout(service => service.Ping(), service => service.Connect(), _cts.Token), + async () => await PingByTimeout(service => service.Ping(), service => service.Connect(_id), _cts.Token), _cts.Token); return result; @@ -72,7 +73,7 @@ public async Task DisconnectAsync() if (_task != null) await _task; - TryCall(service => service.Disconnect()); + TryCall(service => service.Disconnect(_id)); } catch (Exception ex) { diff --git a/AutoPrintr/AutoPrintr/Helpers/WpfApp.cs b/AutoPrintr/AutoPrintr/Helpers/WpfApp.cs index b0f5207..c26c70a 100644 --- a/AutoPrintr/AutoPrintr/Helpers/WpfApp.cs +++ b/AutoPrintr/AutoPrintr/Helpers/WpfApp.cs @@ -65,13 +65,13 @@ public override async Task Startup(string[] args) { NavigationService.NavigateTo(ViewType.Login.ToString()); } - else if (openSettings) + + await ConnectWindowsServiceClient(); + if (SettingsService.Settings.User != null && openSettings) { NavigationService.NavigateTo(ViewType.Settings.ToString()); } - await ConnectWindowsServiceClient(); - //CheckForUpdates(); } @@ -86,7 +86,7 @@ protected override void RegisterTypes() SimpleIoc.Default.Register(); SimpleIoc.Default.Register(); - SimpleIoc.Default.Register(); + SimpleIoc.Default.Register(true); //Register ViewModels SimpleIoc.Default.Register(true); From 31452504fec3914e5a864ecff11fabaf296cbe3e Mon Sep 17 00:00:00 2001 From: Mikhail Shcherbakov Date: Tue, 6 Feb 2018 00:15:01 +0300 Subject: [PATCH 12/17] Fix twice Disconnect() calling when the service is restarting. --- .../Helpers/WindowsServiceClient.cs | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/AutoPrintr/AutoPrintr/Helpers/WindowsServiceClient.cs b/AutoPrintr/AutoPrintr/Helpers/WindowsServiceClient.cs index 9642dee..2885147 100644 --- a/AutoPrintr/AutoPrintr/Helpers/WindowsServiceClient.cs +++ b/AutoPrintr/AutoPrintr/Helpers/WindowsServiceClient.cs @@ -38,11 +38,7 @@ public WindowsServiceClient(ILoggerService loggerService) #region Methods public async Task ConnectAsync(Action connectionFailed) { - if (_cts != null && _task != null) - { - await DisconnectAsync(); - } - + await DisconnectAsync(); _connectionFailed = connectionFailed; bool result; @@ -68,12 +64,19 @@ public async Task DisconnectAsync() { try { - _cts?.Cancel(); + if (_cts != null) + { + _cts.Cancel(); + _cts = null; - if (_task != null) - await _task; + if (_task != null) + { + await _task; + _task = null; - TryCall(service => service.Disconnect(_id)); + TryCall(service => service.Disconnect(_id)); + } + } } catch (Exception ex) { From 8e57d58ed6d821ac813ec7f353dacef41af26458 Mon Sep 17 00:00:00 2001 From: Mikhail Shcherbakov Date: Tue, 6 Feb 2018 01:04:10 +0300 Subject: [PATCH 13/17] Change a version to 2.0.23. --- AutoPrintr/AssemblyVersion.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AutoPrintr/AssemblyVersion.cs b/AutoPrintr/AssemblyVersion.cs index a4d57b8..8f46304 100644 --- a/AutoPrintr/AssemblyVersion.cs +++ b/AutoPrintr/AssemblyVersion.cs @@ -18,5 +18,5 @@ // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("2.0.22.0")] -[assembly: AssemblyFileVersion("2.0.22.0")] +[assembly: AssemblyVersion("2.0.23.0")] +[assembly: AssemblyFileVersion("2.0.23.0")] From f52e4ee825b0ca40aed8435932fb994a3c721b4a Mon Sep 17 00:00:00 2001 From: Mikhail Shcherbakov Date: Wed, 7 Feb 2018 20:58:29 +0300 Subject: [PATCH 14/17] Move up Settings form to hide the right scrollbar. --- AutoPrintr/AutoPrintr/Views/SettingsWindow.xaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AutoPrintr/AutoPrintr/Views/SettingsWindow.xaml b/AutoPrintr/AutoPrintr/Views/SettingsWindow.xaml index d29cb32..992b0bb 100644 --- a/AutoPrintr/AutoPrintr/Views/SettingsWindow.xaml +++ b/AutoPrintr/AutoPrintr/Views/SettingsWindow.xaml @@ -105,7 +105,7 @@ - + - + From 184f62e214469870eb939317910187cdac9dec15 Mon Sep 17 00:00:00 2001 From: Mikhail Shcherbakov Date: Wed, 7 Feb 2018 21:22:23 +0300 Subject: [PATCH 15/17] Maximize Settings window and change margins. --- AutoPrintr/AutoPrintr/Views/SettingsWindow.xaml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/AutoPrintr/AutoPrintr/Views/SettingsWindow.xaml b/AutoPrintr/AutoPrintr/Views/SettingsWindow.xaml index 992b0bb..c30003e 100644 --- a/AutoPrintr/AutoPrintr/Views/SettingsWindow.xaml +++ b/AutoPrintr/AutoPrintr/Views/SettingsWindow.xaml @@ -8,7 +8,9 @@ WindowStartupLocation="CenterScreen" Icon="/AutoPrintr;component/Resources/Printer_32.png" Height="720" - Width="1280"> + Width="1100" + WindowState="Maximized" + SizeToContent="Manual"> 35 @@ -105,9 +107,9 @@ - + - + - - + + From 802b50358f5590ea27730af988ab4aee87581130 Mon Sep 17 00:00:00 2001 From: Mikhail Shcherbakov Date: Wed, 7 Feb 2018 23:46:06 +0300 Subject: [PATCH 16/17] Revert maximazed Settings window. --- AutoPrintr/AutoPrintr/Views/SettingsWindow.xaml | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/AutoPrintr/AutoPrintr/Views/SettingsWindow.xaml b/AutoPrintr/AutoPrintr/Views/SettingsWindow.xaml index c30003e..748f91a 100644 --- a/AutoPrintr/AutoPrintr/Views/SettingsWindow.xaml +++ b/AutoPrintr/AutoPrintr/Views/SettingsWindow.xaml @@ -8,9 +8,7 @@ WindowStartupLocation="CenterScreen" Icon="/AutoPrintr;component/Resources/Printer_32.png" Height="720" - Width="1100" - WindowState="Maximized" - SizeToContent="Manual"> + Width="1280"> 35 @@ -107,9 +105,9 @@ - + - + - - + + From a711b869c1b82aaaeaa20daec31e6308a44e75d1 Mon Sep 17 00:00:00 2001 From: Mikhail Shcherbakov Date: Thu, 8 Feb 2018 00:35:41 +0300 Subject: [PATCH 17/17] Change margins again. --- AutoPrintr/AutoPrintr/Views/SettingsWindow.xaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/AutoPrintr/AutoPrintr/Views/SettingsWindow.xaml b/AutoPrintr/AutoPrintr/Views/SettingsWindow.xaml index 748f91a..f8da83d 100644 --- a/AutoPrintr/AutoPrintr/Views/SettingsWindow.xaml +++ b/AutoPrintr/AutoPrintr/Views/SettingsWindow.xaml @@ -105,9 +105,9 @@ - + - + - - + +