From 2811a2ea291562d2cf99dd08fdf990899ac708aa Mon Sep 17 00:00:00 2001 From: Marco Batzinger Date: Wed, 14 Apr 2021 14:52:51 +0200 Subject: [PATCH] using HKCU for printer output path, starting file watcher when receiving first job and restart file watcher, if output path in registry has changed --- .../Interfaces/IDirectoryHelper.cs | 7 ++- .../Interfaces/IExConfig.cs | 6 --- .../Interfaces/IJobService.cs | 7 +++ .../Interfaces/IUserConfig.cs | 6 +++ .../Model/RegistryConfig.cs | 7 --- .../Model/UserRegistryConfig.cs | 10 +++- .../Misc/JobFactory.cs | 6 ++- .../Misc/JobProcessor.cs | 2 +- .../Misc/JobService.cs | 10 ++-- .../Misc/VirtualTcpInputPrinter.cs | 48 +++++++++++++++---- .../DirectoryHelper.cs | 11 +++-- .../RegistryRepository.cs | 4 +- .../Script.cs | 16 +++---- 13 files changed, 94 insertions(+), 46 deletions(-) diff --git a/Common/AmagnoVirtualPrinter.Agent.Core/Interfaces/IDirectoryHelper.cs b/Common/AmagnoVirtualPrinter.Agent.Core/Interfaces/IDirectoryHelper.cs index 7063df2..7fc408c 100644 --- a/Common/AmagnoVirtualPrinter.Agent.Core/Interfaces/IDirectoryHelper.cs +++ b/Common/AmagnoVirtualPrinter.Agent.Core/Interfaces/IDirectoryHelper.cs @@ -1,7 +1,10 @@ -namespace AmagnoVirtualPrinter.Agent.Core.Interfaces +using JetBrains.Annotations; + +namespace AmagnoVirtualPrinter.Agent.Core.Interfaces { public interface IDirectoryHelper { - string GetOutputDirectory(IExConfig config); + [NotNull] + string GetOutputDirectory([NotNull] IUserConfig config); } } \ No newline at end of file diff --git a/Common/AmagnoVirtualPrinter.Agent.Core/Interfaces/IExConfig.cs b/Common/AmagnoVirtualPrinter.Agent.Core/Interfaces/IExConfig.cs index fdd29e4..30e7d6a 100644 --- a/Common/AmagnoVirtualPrinter.Agent.Core/Interfaces/IExConfig.cs +++ b/Common/AmagnoVirtualPrinter.Agent.Core/Interfaces/IExConfig.cs @@ -20,12 +20,6 @@ public interface IExConfig : IConfig [NotNull] Tuple ResolvedPostconverter { get; } - /// - /// The full path of the output directory. - /// - [NotNull] - string ResolvedOutputDirectory { get; } - /// /// An intermediate format which is read by the printer or similar. /// diff --git a/Common/AmagnoVirtualPrinter.Agent.Core/Interfaces/IJobService.cs b/Common/AmagnoVirtualPrinter.Agent.Core/Interfaces/IJobService.cs index c5eecdc..7f490fa 100644 --- a/Common/AmagnoVirtualPrinter.Agent.Core/Interfaces/IJobService.cs +++ b/Common/AmagnoVirtualPrinter.Agent.Core/Interfaces/IJobService.cs @@ -43,5 +43,12 @@ public interface IJobService /// The path to the ini file /// JobStatus ReadJobStatus(string iniPath); + + /// + /// Gets the + /// + /// The path to the ini file + /// + SessionInfo GetSessionInfo(string iniFile); } } diff --git a/Common/AmagnoVirtualPrinter.Agent.Core/Interfaces/IUserConfig.cs b/Common/AmagnoVirtualPrinter.Agent.Core/Interfaces/IUserConfig.cs index b476870..d2e2c06 100644 --- a/Common/AmagnoVirtualPrinter.Agent.Core/Interfaces/IUserConfig.cs +++ b/Common/AmagnoVirtualPrinter.Agent.Core/Interfaces/IUserConfig.cs @@ -22,5 +22,11 @@ public interface IUserConfig /// Intital value is PDF [NotNull] string Format { get; } + + /// + /// The full path of the output directory. + /// + [NotNull] + string ResolvedOutputDirectory { get; } } } \ No newline at end of file diff --git a/Common/AmagnoVirtualPrinter.Agent.Core/Model/RegistryConfig.cs b/Common/AmagnoVirtualPrinter.Agent.Core/Model/RegistryConfig.cs index a472910..37c4748 100644 --- a/Common/AmagnoVirtualPrinter.Agent.Core/Model/RegistryConfig.cs +++ b/Common/AmagnoVirtualPrinter.Agent.Core/Model/RegistryConfig.cs @@ -13,8 +13,6 @@ public class RegistryConfig : IExConfig public string Preconverter { get; set; } - public string OutputDirectory { get; set; } - public string FileNameMask { get; set; } public short PrinterPort { get; set; } @@ -29,11 +27,6 @@ public Tuple ResolvedPostconverter get { return GetResolvedArgs(Postconverter); } } - public string ResolvedOutputDirectory - { - get { return string.IsNullOrWhiteSpace(OutputDirectory) ? "" : Path.GetFullPath(OutputDirectory); } - } - public IntermediateFormat IntermediateFormat { get; set; } [NotNull] diff --git a/Common/AmagnoVirtualPrinter.Agent.Core/Model/UserRegistryConfig.cs b/Common/AmagnoVirtualPrinter.Agent.Core/Model/UserRegistryConfig.cs index 9c388ca..8cab9d5 100644 --- a/Common/AmagnoVirtualPrinter.Agent.Core/Model/UserRegistryConfig.cs +++ b/Common/AmagnoVirtualPrinter.Agent.Core/Model/UserRegistryConfig.cs @@ -1,4 +1,5 @@ -using AmagnoVirtualPrinter.Agent.Core.Interfaces; +using System.IO; +using AmagnoVirtualPrinter.Agent.Core.Interfaces; namespace AmagnoVirtualPrinter.Agent.Core.Model { @@ -11,5 +12,12 @@ public class UserRegistryConfig : IUserConfig public double? UserRenderDpi { get; set; } public string Format { get; set; } + + public string OutputDirectory { get; set; } + + public string ResolvedOutputDirectory + { + get { return string.IsNullOrWhiteSpace(OutputDirectory) ? "" : Path.GetFullPath(OutputDirectory); } + } } } \ No newline at end of file diff --git a/Common/AmagnoVirtualPrinter.Agent.Lib/Misc/JobFactory.cs b/Common/AmagnoVirtualPrinter.Agent.Lib/Misc/JobFactory.cs index c10507c..cd748c3 100644 --- a/Common/AmagnoVirtualPrinter.Agent.Lib/Misc/JobFactory.cs +++ b/Common/AmagnoVirtualPrinter.Agent.Lib/Misc/JobFactory.cs @@ -66,8 +66,7 @@ public IJob Create(string printerName, Stream stream) try { var now = DateTime.Now; - var config = _registryRepository.GetRegistryConfig(); - var root = _directoryHelper.GetOutputDirectory(config); + var jobInfo = GetCurrentPrintJobs(printerName).FirstOrDefault(); if (jobInfo == null) { @@ -75,6 +74,9 @@ public IJob Create(string printerName, Stream stream) } var session = GetCurrentSessions(jobInfo).FirstOrDefault(); + var config = _registryRepository.GetRegistryConfig(); + var userConfig = _registryRepository.GetUserRegistryConfig(session.Sid); + var root = _directoryHelper.GetOutputDirectory(userConfig); var iniName = GenerateFileName(now, jobInfo.JobId, 0, config.FileNameMask, "ini"); var iniPath = Path.Combine(root, iniName); var extension = GetRawFileExtension(config.IntermediateFormat); diff --git a/Common/AmagnoVirtualPrinter.Agent.Lib/Misc/JobProcessor.cs b/Common/AmagnoVirtualPrinter.Agent.Lib/Misc/JobProcessor.cs index 6fd873b..782273d 100644 --- a/Common/AmagnoVirtualPrinter.Agent.Lib/Misc/JobProcessor.cs +++ b/Common/AmagnoVirtualPrinter.Agent.Lib/Misc/JobProcessor.cs @@ -92,7 +92,7 @@ public void Process(IJob job, IUserConfig userConfig) } var targetFile = $"{Path.GetFileNameWithoutExtension(job.RawDataPath)}"; - var config = _registryRepository.GetRegistryConfig(); + var config = _registryRepository.GetUserRegistryConfig(job.SessionInfo.Sid); var dir = _directoryHelper.GetOutputDirectory(config); targetFile = Path.Combine(dir, targetFile); diff --git a/Common/AmagnoVirtualPrinter.Agent.Lib/Misc/JobService.cs b/Common/AmagnoVirtualPrinter.Agent.Lib/Misc/JobService.cs index 9a8ae1d..ec3a1ef 100644 --- a/Common/AmagnoVirtualPrinter.Agent.Lib/Misc/JobService.cs +++ b/Common/AmagnoVirtualPrinter.Agent.Lib/Misc/JobService.cs @@ -98,9 +98,11 @@ public JobStatus ReadJobStatus(string iniPath) public void Finish(IJob job) { - var config = _registryRepository.GetRegistryConfig(); - WriteJobFinishIni(job.IniDataPath, config); + var userConfig = _registryRepository.GetUserRegistryConfig(job.SessionInfo.Sid); + WriteJobFinishIni(job.IniDataPath, userConfig); + var iniFile = Path.GetFullPath(job.IniDataPath); + var config = _registryRepository.GetRegistryConfig(); var post = config.ResolvedPostconverter; _shell.Execute(job.JobInfo, job.SessionInfo, post.Item1, $"{post.Item2} \"{iniFile}\""); @@ -122,7 +124,7 @@ private void WriteJobStartIni([NotNull]IJob job, PrintStatus status) _shell.WriteIniEntry("Preconverting", "Status", status.ToIni(), job.IniDataPath); } - private SessionInfo GetSessionInfo(string iniFile) + public SessionInfo GetSessionInfo(string iniFile) { var sessionInfo = new SessionInfo { @@ -152,7 +154,7 @@ private JobInfo GetJobInfo(string iniFile) return jobInfo; } - private void WriteJobFinishIni(string iniPath, [NotNull]IExConfig config) + private void WriteJobFinishIni(string iniPath, [NotNull]IUserConfig config) { const PrintStatus status = PrintStatus.Complete; const PrintJobStatus spoolerState = PrintJobStatus.Printed; diff --git a/Common/AmagnoVirtualPrinter.Agent.Lib/Misc/VirtualTcpInputPrinter.cs b/Common/AmagnoVirtualPrinter.Agent.Lib/Misc/VirtualTcpInputPrinter.cs index b3d28c3..daf7f36 100644 --- a/Common/AmagnoVirtualPrinter.Agent.Lib/Misc/VirtualTcpInputPrinter.cs +++ b/Common/AmagnoVirtualPrinter.Agent.Lib/Misc/VirtualTcpInputPrinter.cs @@ -54,15 +54,29 @@ [NotNull]IDirectoryHelper directoryHelper public void Dispose() { - _watcher.Dispose(); + _watcher?.Dispose(); _socket.Stop(); } public void Init() { - var config = GetRegistryConfig(); + try + { + var config = GetRegistryConfig(); + _socket = new TcpListener(IPAddress.Loopback, config.PrinterPort); + _socket.Start(); + _socket.BeginAcceptTcpClient(HandleClient, _socket); - var dir = _directoryHelper.GetOutputDirectory(config); + LogDebug($"Waiting on {_socket.LocalEndpoint}..."); + } + catch (Exception e) + { + LogError(e, "Error initializing tcp input printer"); + } + } + + private void StartFileWatcher([NotNull] string dir) + { _watcher = new FileSystemWatcher(dir, "*.ini") { IncludeSubdirectories = false, @@ -70,11 +84,7 @@ public void Init() EnableRaisingEvents = true }; _watcher.Changed += IniFileChanged; - _socket = new TcpListener(IPAddress.Loopback, config.PrinterPort); - _socket.Start(); - _socket.BeginAcceptTcpClient(HandleClient, _socket); - - LogDebug($"Waiting on {_socket.LocalEndpoint}..."); + LogDebug("Setting file watcher on folder @{dir}", dir); } private void HandleClient([NotNull]IAsyncResult ar) @@ -101,6 +111,19 @@ private void HandleClient([NotNull]IAsyncResult ar) socket.BeginAcceptTcpClient(HandleClient, ar.AsyncState); _jobService.Start(job); + + RestartFileWatcherIfNeeded(job.SessionInfo.Sid); + } + + private void RestartFileWatcherIfNeeded(string sid) + { + var config = GetUserRegistryConfig(sid); + var dir = _directoryHelper.GetOutputDirectory(config); + + if (_watcher == null || _watcher.Path != dir) + { + StartFileWatcher(dir); + } } private void IniFileChanged(object sender, [NotNull]FileSystemEventArgs e) @@ -112,7 +135,8 @@ private void IniFileChanged(object sender, [NotNull]FileSystemEventArgs e) } var rawName = $"{Path.GetFileNameWithoutExtension(ini)}.ps"; - var config = GetRegistryConfig(); + var sessionInfo = _jobService.GetSessionInfo(ini); + var config = GetUserRegistryConfig(sessionInfo.Sid); var dir = _directoryHelper.GetOutputDirectory(config); var rawFile = Path.Combine(dir, rawName); var status = _jobService.ReadStatus(ini); @@ -195,6 +219,12 @@ private bool IsFileLocked(string filePath) } } + [NotNull] + private IUserConfig GetUserRegistryConfig(string sid) + { + return _registryRepository.GetUserRegistryConfig(sid); + } + [NotNull] private IExConfig GetRegistryConfig() { diff --git a/Common/AmagnoVirtualPrinter.Utils/DirectoryHelper.cs b/Common/AmagnoVirtualPrinter.Utils/DirectoryHelper.cs index d713cb9..7002340 100644 --- a/Common/AmagnoVirtualPrinter.Utils/DirectoryHelper.cs +++ b/Common/AmagnoVirtualPrinter.Utils/DirectoryHelper.cs @@ -1,13 +1,18 @@ -using System.IO; +using System; +using System.IO; using AmagnoVirtualPrinter.Agent.Core.Interfaces; -using AmagnoVirtualPrinter.Agent.Core; namespace AmagnoVirtualPrinter.Utils { public class DirectoryHelper : IDirectoryHelper { - public string GetOutputDirectory(IExConfig config) + public string GetOutputDirectory(IUserConfig config) { + if (config == null) + { + throw new ArgumentNullException(nameof(config)); + } + if (string.IsNullOrWhiteSpace(config.ResolvedOutputDirectory)) { var outputDir = Path.Combine(Path.GetTempPath(), "PrinterOutput"); diff --git a/Common/AmagnoVirtualPrinter.Utils/RegistryRepository.cs b/Common/AmagnoVirtualPrinter.Utils/RegistryRepository.cs index 8b8beb2..6de34b7 100644 --- a/Common/AmagnoVirtualPrinter.Utils/RegistryRepository.cs +++ b/Common/AmagnoVirtualPrinter.Utils/RegistryRepository.cs @@ -8,8 +8,6 @@ using Microsoft.Win32; -using AmagnoVirtualPrinter.Agent.Core; - namespace AmagnoVirtualPrinter.Utils { public class RegistryRepository : IRegistryRepository @@ -84,7 +82,6 @@ public IExConfig GetRegistryConfig() using (var key = driver.OpenSubKey(Keys.CONVERTER_KEY)) { CheckForNull(key, Keys.CONVERTER_KEY); - registryConfig.OutputDirectory = key.GetValue(KeyNames.OUTPUT_DIR).ToString(); registryConfig.FileNameMask = key.GetValue(KeyNames.FILE_NAME_MASK).ToString(); var portStr = key.GetValue(KeyNames.SERVER_PORT).ToString(); registryConfig.PrinterPort = short.TryParse(portStr, out var portVal) ? portVal : DefaultServerPort; @@ -120,6 +117,7 @@ public IUserConfig GetUserRegistryConfig(string sid) using (var converter = driver.OpenSubKey(Keys.CONVERTER_KEY)) { CheckForNull(converter, Keys.CONVERTER_KEY); + userConfig.OutputDirectory = converter.GetValue(KeyNames.OUTPUT_DIR).ToString(); subKey = "Redirect"; using (var redirect = converter.OpenSubKey(subKey)) diff --git a/Installer/AmagnoVirtualPrinter.WixSharpInstaller/Script.cs b/Installer/AmagnoVirtualPrinter.WixSharpInstaller/Script.cs index d18db05..acb667a 100644 --- a/Installer/AmagnoVirtualPrinter.WixSharpInstaller/Script.cs +++ b/Installer/AmagnoVirtualPrinter.WixSharpInstaller/Script.cs @@ -134,8 +134,8 @@ File printerServiceFile @"%ProgramFiles%\AmagnoPrinterDriver\", new DirFiles(feature, _filesDir + @"\*", s => !s.EndsWith(".exe")), new File(new Id(SetupDriverId), feature, Path.Combine(_filesDir, Utils.Files.SETUP_DRIVER_EXE)), - new File(feature, Path.Combine(_filesDir, Utils.Files.DILIVERY_EXE)), - new File(feature, Path.Combine(_filesDir, Utils.Files.AGENT_PROGRESS_EXE)), + new File(feature, Path.Combine(_filesDir, Files.DILIVERY_EXE)), + new File(feature, Path.Combine(_filesDir, Files.AGENT_PROGRESS_EXE)), printerServiceFile ) }; @@ -154,7 +154,7 @@ private static Action[] CreateActions() [NotNull] private static IEnumerable CreateRegValues(Feature feature) { - var converterKey = $@"{Utils.Keys.PRINTER_DRIVER_KEY32}\{Utils.Keys.CONVERTER_KEY}"; + var converterKey = $@"{Keys.PRINTER_DRIVER_KEY32}\{Keys.CONVERTER_KEY}"; var regValues = new List(); regValues.AddRange(CreateLocalMachineValues(feature, converterKey)); @@ -166,10 +166,10 @@ private static IEnumerable CreateRegValues(Feature feature) [NotNull] private static IEnumerable CreateLocalMachineValues(Feature feature, string converterKey) { - var postConverterKey = $@"{Utils.Keys.PRINTER_DRIVER_KEY32}\{Utils.Keys.POSTCONVERTER_KEY}"; - var preConverterKey = $@"{Utils.Keys.PRINTER_DRIVER_KEY32}\{Utils.Keys.PRECONVERTER_KEY}"; - var converterPdfKey = $@"{Utils.Keys.PRINTER_DRIVER_KEY32}\{Utils.Keys.CONVERTER_PDF_KEY}"; - var converterTiffKey = $@"{Utils.Keys.PRINTER_DRIVER_KEY32}\{Utils.Keys.CONVERTER_TIFF_KEY}"; + var postConverterKey = $@"{Keys.PRINTER_DRIVER_KEY32}\{Keys.POSTCONVERTER_KEY}"; + var preConverterKey = $@"{Keys.PRINTER_DRIVER_KEY32}\{Keys.PRECONVERTER_KEY}"; + var converterPdfKey = $@"{Keys.PRINTER_DRIVER_KEY32}\{Keys.CONVERTER_PDF_KEY}"; + var converterTiffKey = $@"{Keys.PRINTER_DRIVER_KEY32}\{Keys.CONVERTER_TIFF_KEY}"; var registryHive = RegistryHive.LocalMachine; var result = new List @@ -180,7 +180,6 @@ private static IEnumerable CreateLocalMachineValues(Feature feature, s new RegValue(feature, registryHive, converterKey, KeyNames.SHOW_PROGRESS, 1) {AttributesDefinition = "Type=integer"}, new RegValue(feature, registryHive, converterKey, KeyNames.PAGES_PER_SHEET, 1), new RegValue(feature, registryHive, converterKey, KeyNames.FILE_NAME_MASK, "{yyyy}{MM}{DD}{hh}{mm}{ss}{job05}{page03}"), - new RegValue(feature, registryHive, converterKey, KeyNames.OUTPUT_DIR, string.Empty), new RegValue(feature, registryHive, converterKey, KeyNames.FORMAT, "ps"), new RegValue(feature, registryHive, converterPdfKey, KeyNames.ENABLED, 1) {AttributesDefinition = "Type=integer"}, new RegValue(feature, registryHive, converterPdfKey, KeyNames.MULTIPAGE, 1) {AttributesDefinition = "Type=integer"}, @@ -221,6 +220,7 @@ private static IEnumerable CreateCurrentUserValues(Feature feature, st { new RegValue(feature, registryHive, converterKey, KeyNames.PRINT_FORMAT, "PDF"), new RegValue(feature, registryHive, converterKey, KeyNames.RENDER_DPI, 300) {AttributesDefinition = "Type=integer"}, + new RegValue(feature, registryHive, converterKey, KeyNames.OUTPUT_DIR, string.Empty), new RegValue(feature, registryHive, redirectKey, KeyNames.ENABLED, 1) {AttributesDefinition = "Type=integer"}, new RegValue(feature, registryHive, redirectKey, KeyNames.PRINTER, "") };