Implemented VirtualPrinterDriver project
This commit is contained in:
parent
f29c84821b
commit
5c87967c3f
125 changed files with 8191 additions and 0 deletions
218
Common/VirtualPrinter.Agent.Lib/Misc/GhostScriptConverter.cs
Normal file
218
Common/VirtualPrinter.Agent.Lib/Misc/GhostScriptConverter.cs
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
using VirtualPrinter.Agent.Core;
|
||||
using VirtualPrinter.Agent.Lib.Model;
|
||||
using VirtualPrinter.Logging;
|
||||
|
||||
namespace VirtualPrinter.Agent.Lib.Misc
|
||||
{
|
||||
public class GhostScriptConverter : IPostScriptConverter
|
||||
{
|
||||
private const string GsWin64 = "gswin64c.exe";
|
||||
private const string GsWin32 = "gswin32c.exe";
|
||||
|
||||
[NotNull]
|
||||
private readonly IVirtualPrinterLogger<GhostScriptConverter> _logger;
|
||||
|
||||
[NotNull]
|
||||
private readonly IRegistryRepository _registryRepository;
|
||||
|
||||
[NotNull]
|
||||
private readonly IShell _shell;
|
||||
|
||||
public event EventHandler<IJob> ProgressInitialized;
|
||||
public event EventHandler<IJob> ProgressFinished;
|
||||
public event EventHandler<ProgressUpdateArgs> ProgressUpdate;
|
||||
|
||||
public GhostScriptConverter
|
||||
(
|
||||
[NotNull]IVirtualPrinterLogger<GhostScriptConverter> logger,
|
||||
[NotNull]IRegistryRepository registryRepository,
|
||||
[NotNull]IShell shell
|
||||
)
|
||||
{
|
||||
if (logger == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
|
||||
if (registryRepository == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(registryRepository));
|
||||
}
|
||||
|
||||
if (shell == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(shell));
|
||||
}
|
||||
|
||||
_logger = logger;
|
||||
_registryRepository = registryRepository;
|
||||
_shell = shell;
|
||||
}
|
||||
|
||||
public void Convert(IJob job, string target, PostScriptRenderOptions options)
|
||||
{
|
||||
var ghostScriptExe = GetGhostScriptPath();
|
||||
|
||||
if (ghostScriptExe == null)
|
||||
{
|
||||
throw new PostScriptConversionException("GhostScript not found. Please place local variable.");
|
||||
}
|
||||
|
||||
ProgressInitialized?.Invoke(this, job);
|
||||
|
||||
var pdfTarget = target + ".pdf";
|
||||
if (options.PdfOptions.Enabled)
|
||||
{
|
||||
Convert(job, ghostScriptExe, GetArgumentsForPdfConversion(job.RawDataPath, pdfTarget, options));
|
||||
|
||||
if (!_shell.FileExists(pdfTarget))
|
||||
{
|
||||
throw new PostScriptConversionException("Postscript conversion failed after output.");
|
||||
}
|
||||
}
|
||||
|
||||
if (options.TiffOptions.Enabled)
|
||||
{
|
||||
var tiffTarget = target + ".tif";
|
||||
|
||||
Convert(job, ghostScriptExe, GetArgumentsForTiffConversion(job.RawDataPath, tiffTarget, options));
|
||||
Convert(job, ghostScriptExe, GetArgumentsForPdfConversion(job.RawDataPath, pdfTarget, options));
|
||||
|
||||
if (!_shell.FileExists(tiffTarget))
|
||||
{
|
||||
throw new PostScriptConversionException("Postscript conversion failed after output.");
|
||||
}
|
||||
}
|
||||
|
||||
ProgressFinished?.Invoke(this, job);
|
||||
}
|
||||
|
||||
[CanBeNull]
|
||||
private string GetGhostScriptPath()
|
||||
{
|
||||
return GetGhostScriptPath(GsWin64) ?? GetGhostScriptPath(GsWin32);
|
||||
}
|
||||
|
||||
[CanBeNull]
|
||||
private string GetGhostScriptPath(string execName)
|
||||
{
|
||||
if (!_registryRepository.TryGetGhostscriptPath(out var path))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var ghostScriptBinPath = Path.Combine(path, "bin");
|
||||
var fullPath = Path.Combine(ghostScriptBinPath, execName);
|
||||
|
||||
return _shell.FileExists(fullPath) ? fullPath : null;
|
||||
}
|
||||
|
||||
[NotNull]
|
||||
private static string GetArgumentsForPdfConversion(string source, string target, PostScriptRenderOptions options)
|
||||
{
|
||||
const string initialArguments = "-q -P- -dSAFER -dNOPAUSE -dBATCH -dNoCancel -sDEVICE=pdfwrite";
|
||||
var finalArguments = $"-sOutputFile=\"{target}\" \"{source}\"";
|
||||
|
||||
var optionalArguments = "";
|
||||
|
||||
if (options.PdfOptions.Archivable)
|
||||
{
|
||||
optionalArguments += "-sColorConversionStrategy=/RGB -dUseCIEColor -dPDFACompatibilityPolicy=2";
|
||||
}
|
||||
|
||||
if (options.UserRenderDpi != null && options.UserRenderDpi > 0)
|
||||
{
|
||||
optionalArguments += "-r" + options.UserRenderDpi.Value;
|
||||
}
|
||||
|
||||
return $"{initialArguments} {optionalArguments} {finalArguments}";
|
||||
}
|
||||
|
||||
[NotNull]
|
||||
private static string GetArgumentsForTiffConversion(string source, string target, PostScriptRenderOptions options)
|
||||
{
|
||||
const string initialArguments = "-q -P- -dSAFER -dNOPAUSE -dBATCH -sDEVICE=tiff12nc -sCompression=lzw";
|
||||
var finalArguments = $"-sOutputFile=\"{target}\" \"{source}\"";
|
||||
|
||||
var optionalArguments = "-dTextAlphaBits=4 ";
|
||||
|
||||
if (options.UserRenderDpi != null && options.UserRenderDpi > 0)
|
||||
{
|
||||
optionalArguments += "-r" + options.UserRenderDpi.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
optionalArguments += "-r300";
|
||||
}
|
||||
|
||||
return $"{initialArguments} {optionalArguments} {finalArguments}";
|
||||
}
|
||||
|
||||
private void Convert(IJob job, string gsExe, string gsArguments)
|
||||
{
|
||||
LogDebug("Starting ps conversion ...\n"+gsExe + " " + gsArguments);
|
||||
|
||||
var process = new Process
|
||||
{
|
||||
StartInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = gsExe,
|
||||
Arguments = gsArguments,
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
CreateNoWindow = true
|
||||
}
|
||||
};
|
||||
|
||||
process.Start();
|
||||
|
||||
while (!process.StandardOutput.EndOfStream)
|
||||
{
|
||||
var readLine = process.StandardOutput.ReadLine();
|
||||
var progress = ParseProgress(readLine);
|
||||
|
||||
if (progress == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ProgressUpdate?.Invoke(this, new ProgressUpdateArgs(job, progress.Value));
|
||||
}
|
||||
}
|
||||
|
||||
private static uint? ParseProgress([CanBeNull]string line)
|
||||
{
|
||||
// Example output:
|
||||
// %%[Page: 49]%%
|
||||
if (line == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var groups = Regex.Match(line, @"%%\[Page:(.*)\]%%").Groups;
|
||||
if (groups.Count < 2)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!uint.TryParse(groups[1].Value, out var result))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void LogDebug(string message, params object[] args)
|
||||
{
|
||||
_logger.Debug(message, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
15
Common/VirtualPrinter.Agent.Lib/Misc/Job.cs
Normal file
15
Common/VirtualPrinter.Agent.Lib/Misc/Job.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
using VirtualPrinter.Agent.Core;
|
||||
|
||||
namespace VirtualPrinter.Agent.Lib.Misc
|
||||
{
|
||||
public class Job : IJob
|
||||
{
|
||||
public string RawDataPath { get; set; }
|
||||
|
||||
public string IniDataPath { get; set; }
|
||||
|
||||
public IJobInfo JobInfo { get; set; }
|
||||
|
||||
public ISessionInfo SessionInfo { get; set; }
|
||||
}
|
||||
}
|
||||
243
Common/VirtualPrinter.Agent.Lib/Misc/JobFactory.cs
Normal file
243
Common/VirtualPrinter.Agent.Lib/Misc/JobFactory.cs
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Printing;
|
||||
using System.Security.Principal;
|
||||
|
||||
using Cassia;
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
using VirtualPrinter.Agent.Core;
|
||||
using VirtualPrinter.Agent.Core.Enums;
|
||||
using VirtualPrinter.Logging;
|
||||
|
||||
namespace VirtualPrinter.Agent.Lib.Misc
|
||||
{
|
||||
public class JobFactory : IJobFactory
|
||||
{
|
||||
[NotNull]
|
||||
private readonly IVirtualPrinterLogger<JobFactory> _logger;
|
||||
private readonly IDirectoryHelper _directoryHelper;
|
||||
[NotNull]
|
||||
private readonly IRegistryRepository _registryRepository;
|
||||
|
||||
public JobFactory
|
||||
(
|
||||
[NotNull]IRegistryRepository registryRepository,
|
||||
[NotNull]IVirtualPrinterLogger<JobFactory> logger,
|
||||
[NotNull]IDirectoryHelper directoryHelper
|
||||
)
|
||||
{
|
||||
if (registryRepository == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(registryRepository));
|
||||
}
|
||||
|
||||
if (logger == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
|
||||
if (directoryHelper == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
|
||||
_registryRepository = registryRepository;
|
||||
_logger = logger;
|
||||
_directoryHelper = directoryHelper;
|
||||
}
|
||||
|
||||
public IJob Create(string printerName, Stream stream)
|
||||
{
|
||||
if (printerName == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(printerName));
|
||||
}
|
||||
|
||||
if (stream == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(stream));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
var config = _registryRepository.GetRegistryConfig();
|
||||
var root = _directoryHelper.GetOutputDirectory(config);
|
||||
var jobInfo = GetCurrentPrintJobs(printerName).FirstOrDefault();
|
||||
if (jobInfo == null)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
var session = GetCurrentSessions(jobInfo).FirstOrDefault();
|
||||
var iniName = GenerateFileName(now, jobInfo.JobId, 0, config.FileNameMask, "ini");
|
||||
var iniPath = Path.Combine(root, iniName);
|
||||
var extension = GetRawFileExtension(config.IntermediateFormat);
|
||||
var rawName = $"{Path.GetFileNameWithoutExtension(iniName)}.{extension}";
|
||||
var rawPath = Path.Combine(root, rawName);
|
||||
using (var output = File.Create(rawPath))
|
||||
{
|
||||
stream.CopyTo(output);
|
||||
}
|
||||
|
||||
return new Job
|
||||
{
|
||||
RawDataPath = rawPath,
|
||||
IniDataPath = iniPath,
|
||||
JobInfo = jobInfo,
|
||||
SessionInfo = session
|
||||
};
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
LogError(exception, "Failed to create job.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public IJob Create(string iniPath, string rawPath, IJobInfo jobInfo, ISessionInfo sessionInfo)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(iniPath))
|
||||
{
|
||||
throw new ArgumentException("Value cannot be null or whitespace.", nameof(iniPath));
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(rawPath))
|
||||
{
|
||||
throw new ArgumentException("Value cannot be null or whitespace.", nameof(rawPath));
|
||||
}
|
||||
|
||||
return new Job
|
||||
{
|
||||
IniDataPath = iniPath,
|
||||
RawDataPath = rawPath,
|
||||
JobInfo = jobInfo,
|
||||
SessionInfo = sessionInfo
|
||||
};
|
||||
}
|
||||
|
||||
[NotNull]
|
||||
private string GenerateFileName(DateTime time, int job, int page, [NotNull]string pattern, [NotNull]string ending)
|
||||
{
|
||||
var fileName = pattern;
|
||||
fileName = fileName.Replace("{yyyy}", $"{time.Year:0000}");
|
||||
fileName = fileName.Replace("{MM}", $"{time.Month:00}");
|
||||
fileName = fileName.Replace("{DD}", $"{time.Day:00}");
|
||||
fileName = fileName.Replace("{hh}", $"{time.Hour:00}");
|
||||
fileName = fileName.Replace("{mm}", $"{time.Minute:00}");
|
||||
fileName = fileName.Replace("{ss}", $"{time.Second:00}");
|
||||
fileName = fileName.Replace("{fff}", $"{time.Millisecond:000}");
|
||||
fileName = fileName.Replace("{job05}", $"{job:00000}");
|
||||
fileName = fileName.Replace("{page03}", $"{page:000}");
|
||||
|
||||
return $"{fileName}.{ending}";
|
||||
}
|
||||
|
||||
private IEnumerable<SessionInfo> GetCurrentSessions([NotNull]IJobInfo job)
|
||||
{
|
||||
var domain = job.DomainName;
|
||||
var machine = job.MachineName?.TrimStart('\\');
|
||||
var user = job.UserName;
|
||||
|
||||
LogDebug($"Searching for session of {domain}\\{user} on {machine} !");
|
||||
|
||||
if (domain == null || machine == null || user == null)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
const StringComparison cmp = StringComparison.OrdinalIgnoreCase;
|
||||
using (var server = new TerminalServicesManager().GetLocalServer())
|
||||
{
|
||||
var sessions = server.GetSessions().Where(s => s.UserName != null && s.DomainName != null);
|
||||
foreach (var session in sessions)
|
||||
{
|
||||
if (!session.UserName.Equals(user, cmp))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var isSingleUser = session.DomainName.Equals(machine, cmp);
|
||||
var isDomainUser = session.DomainName.Equals(domain, cmp);
|
||||
if (!isSingleUser && !isDomainUser)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var sessionId = session.SessionId;
|
||||
var desktopName = session.WindowStationName;
|
||||
var account = session.UserAccount;
|
||||
yield return new SessionInfo
|
||||
{
|
||||
Id = sessionId,
|
||||
Desktop = desktopName,
|
||||
Sid = account.Translate(typeof(SecurityIdentifier)).Value
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ItemNotNull]
|
||||
private IEnumerable<IJobInfo> GetCurrentPrintJobs(string printerName)
|
||||
{
|
||||
using (var server = new LocalPrintServer())
|
||||
{
|
||||
using (var queue = server.GetPrintQueue(printerName))
|
||||
{
|
||||
using (var jobs = queue.GetPrintJobInfoCollection())
|
||||
{
|
||||
foreach (var job in jobs)
|
||||
{
|
||||
using (job)
|
||||
{
|
||||
var id = job.JobIdentifier;
|
||||
var machine = server.Name;
|
||||
var domain = Environment.UserDomainName;
|
||||
var user = job.Submitter;
|
||||
var name = job.Name;
|
||||
yield return new JobInfo
|
||||
{
|
||||
JobId = id,
|
||||
Name = name,
|
||||
DomainName = domain,
|
||||
MachineName = machine,
|
||||
UserName = user,
|
||||
Status = job.JobStatus,
|
||||
DeviceName = queue.Name
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[NotNull]
|
||||
private string GetRawFileExtension(IntermediateFormat format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case IntermediateFormat.Xps:
|
||||
return "xps";
|
||||
case IntermediateFormat.Ps:
|
||||
return "ps";
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
private void LogDebug(string message)
|
||||
{
|
||||
_logger.Debug(message);
|
||||
}
|
||||
|
||||
private void LogError(Exception exception, string message, params object[] args)
|
||||
{
|
||||
_logger.Error(exception, message, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
150
Common/VirtualPrinter.Agent.Lib/Misc/JobProcessor.cs
Normal file
150
Common/VirtualPrinter.Agent.Lib/Misc/JobProcessor.cs
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
using VirtualPrinter.Agent.Core;
|
||||
using VirtualPrinter.Agent.Lib.Model;
|
||||
using VirtualPrinter.Logging;
|
||||
using VirtualPrinter.ProgressInfo.Core;
|
||||
|
||||
namespace VirtualPrinter.Agent.Lib.Misc
|
||||
{
|
||||
public class JobProcessor : IJobProcessor
|
||||
{
|
||||
[NotNull]
|
||||
private readonly IRegistryRepository _registryRepository;
|
||||
|
||||
[NotNull]
|
||||
private readonly IJobRedirector _jobRedirector;
|
||||
|
||||
[NotNull]
|
||||
private readonly IVirtualPrinterLogger<JobProcessor> _logger;
|
||||
|
||||
[NotNull]
|
||||
private readonly IPostScriptConverter _postScriptConverter;
|
||||
|
||||
[NotNull]
|
||||
private readonly IProgressInfo _progressInfo;
|
||||
private readonly IDirectoryHelper _directoryHelper;
|
||||
|
||||
public JobProcessor
|
||||
(
|
||||
[NotNull]IRegistryRepository registryRepository,
|
||||
[NotNull]IVirtualPrinterLogger<JobProcessor> logger,
|
||||
[NotNull]IPostScriptConverter postScriptConverter,
|
||||
[NotNull]IJobRedirector redirector,
|
||||
[NotNull]IProgressInfo progressInfo,
|
||||
[NotNull]IDirectoryHelper directoryHelper
|
||||
)
|
||||
{
|
||||
if (registryRepository == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(registryRepository));
|
||||
}
|
||||
|
||||
if (logger == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
|
||||
if (postScriptConverter == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(postScriptConverter));
|
||||
}
|
||||
|
||||
if (redirector == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(redirector));
|
||||
}
|
||||
|
||||
if (progressInfo == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(progressInfo));
|
||||
}
|
||||
|
||||
if (directoryHelper == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(directoryHelper));
|
||||
}
|
||||
|
||||
_registryRepository = registryRepository;
|
||||
_logger = logger;
|
||||
_postScriptConverter = postScriptConverter;
|
||||
_jobRedirector = redirector;
|
||||
_progressInfo = progressInfo;
|
||||
_directoryHelper = directoryHelper;
|
||||
_postScriptConverter.ProgressInitialized += OnProgressInitialized;
|
||||
_postScriptConverter.ProgressFinished += OnProgressFinished;
|
||||
_postScriptConverter.ProgressUpdate += OnProgressUpdate;
|
||||
}
|
||||
|
||||
public void Process(IJob job, IUserConfig userConfig)
|
||||
{
|
||||
if (job == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(job));
|
||||
}
|
||||
|
||||
if (userConfig == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(userConfig));
|
||||
}
|
||||
|
||||
var targetFile = $"{Path.GetFileNameWithoutExtension(job.RawDataPath)}";
|
||||
var config = _registryRepository.GetRegistryConfig();
|
||||
var dir = _directoryHelper.GetOutputDirectory(config);
|
||||
targetFile = Path.Combine(dir, targetFile);
|
||||
|
||||
var options = new PostScriptRenderOptions
|
||||
{
|
||||
UserRenderDpi = userConfig.UserRenderDpi,
|
||||
PdfOptions = new PostScriptRenderPdfOptions
|
||||
{
|
||||
Enabled = userConfig.Format == "PDF" || string.IsNullOrEmpty(userConfig.Format)
|
||||
},
|
||||
TiffOptions = new PostScriptRenderTiffOptions
|
||||
{
|
||||
Enabled = userConfig.Format == "TIFF"
|
||||
}
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
_postScriptConverter.Convert(job, targetFile, options);
|
||||
}
|
||||
catch (PostScriptConversionException exception)
|
||||
{
|
||||
LogError(exception, "Error processing PS file.");
|
||||
return;
|
||||
}
|
||||
|
||||
_jobRedirector.Redirect(job, userConfig);
|
||||
}
|
||||
|
||||
private void OnProgressUpdate(object sender, [NotNull]ProgressUpdateArgs args)
|
||||
{
|
||||
if (args == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(args));
|
||||
}
|
||||
|
||||
_progressInfo.Progress(args.Job, args.Value);
|
||||
}
|
||||
|
||||
private void OnProgressFinished(object sender, IJob job)
|
||||
{
|
||||
_progressInfo.Finish(job);
|
||||
}
|
||||
|
||||
private void OnProgressInitialized(object sender, IJob job)
|
||||
{
|
||||
_progressInfo.Initialize(job);
|
||||
}
|
||||
|
||||
private void LogError(Exception exception, string message, params object[] args)
|
||||
{
|
||||
_logger.Error(exception, message, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
106
Common/VirtualPrinter.Agent.Lib/Misc/JobRedirector.cs
Normal file
106
Common/VirtualPrinter.Agent.Lib/Misc/JobRedirector.cs
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
using VirtualPrinter.Agent.Core;
|
||||
using VirtualPrinter.Delivery;
|
||||
using VirtualPrinter.Logging;
|
||||
using VirtualPrinter.Utils;
|
||||
|
||||
namespace VirtualPrinter.Agent.Lib.Misc
|
||||
{
|
||||
public class JobRedirector : IJobRedirector
|
||||
{
|
||||
[NotNull]
|
||||
private readonly IVirtualPrinterLogger<JobRedirector> _logger;
|
||||
|
||||
[NotNull]
|
||||
private readonly IShell _shell;
|
||||
|
||||
public JobRedirector([NotNull]IVirtualPrinterLogger<JobRedirector> logger, [NotNull]IShell shell)
|
||||
{
|
||||
if (logger == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
|
||||
if (shell == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(shell));
|
||||
}
|
||||
|
||||
_logger = logger;
|
||||
_shell = shell;
|
||||
}
|
||||
|
||||
public void Redirect(IJob job, IUserConfig userConfig)
|
||||
{
|
||||
if (job == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(job));
|
||||
}
|
||||
|
||||
if (userConfig == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(userConfig));
|
||||
}
|
||||
|
||||
var printer = userConfig.RedirectPrinter;
|
||||
if (string.IsNullOrWhiteSpace(printer))
|
||||
{
|
||||
LogWarn("Can not redirect to empty printer.");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var pdfToRedirect = GetPdfPath(job.RawDataPath);
|
||||
|
||||
LogDebug($"Redirecting '{pdfToRedirect}' to '{printer}'...");
|
||||
|
||||
var redirectExe = Path.GetFullPath(typeof(Redirector).Assembly.Location);
|
||||
var redirectArgs = $@"redirect ""{pdfToRedirect}"" ""{printer}""";
|
||||
|
||||
_shell.Execute(job.JobInfo, job.SessionInfo, redirectExe, redirectArgs);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
LogError(exception, $"{exception.GetType()}: {exception.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[NotNull]
|
||||
private static string GetPdfPath([NotNull]string rawFilePath)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(rawFilePath))
|
||||
{
|
||||
throw new ArgumentException(nameof(rawFilePath));
|
||||
}
|
||||
|
||||
var directoryName = Path.GetDirectoryName(rawFilePath);
|
||||
if (string.IsNullOrWhiteSpace(directoryName))
|
||||
{
|
||||
throw new ArgumentException(nameof(directoryName));
|
||||
}
|
||||
|
||||
var file = Path.GetFileNameWithoutExtension(rawFilePath);
|
||||
return Path.Combine(directoryName, file) + ".pdf";
|
||||
}
|
||||
|
||||
private void LogDebug(string message, params object[] args)
|
||||
{
|
||||
_logger.Debug(message, args);
|
||||
}
|
||||
|
||||
private void LogWarn(string message, params object[] args)
|
||||
{
|
||||
_logger.Warn(message, args);
|
||||
}
|
||||
|
||||
private void LogError(Exception exception, string message, params object[] args)
|
||||
{
|
||||
_logger.Error(exception, message, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
170
Common/VirtualPrinter.Agent.Lib/Misc/JobService.cs
Normal file
170
Common/VirtualPrinter.Agent.Lib/Misc/JobService.cs
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Printing;
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
using VirtualPrinter.Agent.Core;
|
||||
|
||||
namespace VirtualPrinter.Agent.Lib.Misc
|
||||
{
|
||||
public class JobService : IJobService
|
||||
{
|
||||
[NotNull]
|
||||
private readonly IRegistryRepository _registryRepository;
|
||||
|
||||
[NotNull]
|
||||
private readonly IJobFactory _jobFactory;
|
||||
|
||||
[NotNull]
|
||||
private readonly IShell _shell;
|
||||
private IDirectoryHelper _directoryHelper;
|
||||
|
||||
public JobService
|
||||
(
|
||||
[NotNull]IRegistryRepository registryRepository,
|
||||
[NotNull]IJobFactory jobFactory,
|
||||
[NotNull]IShell shell,
|
||||
[NotNull]IDirectoryHelper directoryHelper
|
||||
)
|
||||
{
|
||||
if (registryRepository == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(registryRepository));
|
||||
}
|
||||
|
||||
if (jobFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(jobFactory));
|
||||
}
|
||||
|
||||
if (shell == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(shell));
|
||||
}
|
||||
|
||||
if (directoryHelper == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(directoryHelper));
|
||||
}
|
||||
|
||||
_registryRepository = registryRepository;
|
||||
_jobFactory = jobFactory;
|
||||
_shell = shell;
|
||||
_directoryHelper = directoryHelper;
|
||||
}
|
||||
|
||||
public void Start(IJob job)
|
||||
{
|
||||
if (job == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(job));
|
||||
}
|
||||
|
||||
const PrintStatus status = PrintStatus.Paused;
|
||||
|
||||
var iniFile = Path.GetFullPath(job.IniDataPath);
|
||||
var config = _registryRepository.GetRegistryConfig();
|
||||
var pre = config.ResolvedPreconverter;
|
||||
WriteJobStartIni(job, status);
|
||||
|
||||
_shell.Execute(job.JobInfo, job.SessionInfo, pre.Item1, $"{pre.Item2} \"{iniFile}\"");
|
||||
}
|
||||
|
||||
public IJob CreateJob(string iniFile, string rawFile)
|
||||
{
|
||||
var jobInfo = GetJobInfo(iniFile);
|
||||
|
||||
var sessionInfo = GetSessionInfo(iniFile);
|
||||
|
||||
return _jobFactory.Create(iniFile, rawFile, jobInfo, sessionInfo);
|
||||
}
|
||||
|
||||
public PrintStatus ReadStatus(string iniPath)
|
||||
{
|
||||
var txt = _shell.ReadIniEntry<string>("Preconverting", "Status", iniPath);
|
||||
Enum.TryParse(txt, true, out PrintStatus result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public JobStatus ReadJobStatus(string iniPath)
|
||||
{
|
||||
var status = _shell.ReadIniEntry<string>("Job", "Status", iniPath);
|
||||
Enum.TryParse(status, true, out JobStatus result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void Finish(IJob job)
|
||||
{
|
||||
var config = _registryRepository.GetRegistryConfig();
|
||||
WriteJobFinishIni(job.IniDataPath, config);
|
||||
var iniFile = Path.GetFullPath(job.IniDataPath);
|
||||
var post = config.ResolvedPostconverter;
|
||||
|
||||
_shell.Execute(job.JobInfo, job.SessionInfo, post.Item1, $"{post.Item2} \"{iniFile}\"");
|
||||
}
|
||||
|
||||
private void WriteJobStartIni([NotNull]IJob job, PrintStatus status)
|
||||
{
|
||||
_shell.WriteIniEntry("Job", "Status", JobStatus.InProgress.ToString().ToLowerInvariant(), job.IniDataPath);
|
||||
_shell.WriteIniEntry("Device", "DeviceName", job.JobInfo.DeviceName, job.IniDataPath);
|
||||
_shell.WriteIniEntry("Document", "Name", job.JobInfo.Name.Normalize(), job.IniDataPath);
|
||||
_shell.WriteIniEntry("Document", "JobID", $"{job.JobInfo.JobId}", job.IniDataPath);
|
||||
_shell.WriteIniEntry("Document", "DomainName", job.JobInfo.DomainName, job.IniDataPath);
|
||||
_shell.WriteIniEntry("Document", "MachineName", job.JobInfo.MachineName, job.IniDataPath);
|
||||
_shell.WriteIniEntry("Document", "UserName", job.JobInfo.UserName, job.IniDataPath);
|
||||
_shell.WriteIniEntry("Document", "SessionID", $"{job.SessionInfo.Id}", job.IniDataPath);
|
||||
_shell.WriteIniEntry("Document", "Desktop", $"{job.SessionInfo.Desktop}", job.IniDataPath);
|
||||
_shell.WriteIniEntry("Document", "SID", $"{job.SessionInfo.Sid}", job.IniDataPath);
|
||||
_shell.WriteIniEntry("Document", "Status", job.JobInfo.Status.ToString(), job.IniDataPath);
|
||||
_shell.WriteIniEntry("Preconverting", "Status", status.ToIni(), job.IniDataPath);
|
||||
}
|
||||
|
||||
private SessionInfo GetSessionInfo(string iniFile)
|
||||
{
|
||||
var sessionInfo = new SessionInfo
|
||||
{
|
||||
Id = _shell.ReadIniEntry<int>("Document",
|
||||
"SessionID",
|
||||
iniFile),
|
||||
Sid = _shell.ReadIniEntry<string>("Document", "SID", iniFile),
|
||||
Desktop = _shell.ReadIniEntry<string>("Document", "Desktop", iniFile)
|
||||
};
|
||||
return sessionInfo;
|
||||
}
|
||||
|
||||
private JobInfo GetJobInfo(string iniFile)
|
||||
{
|
||||
var jobInfo = new JobInfo
|
||||
{
|
||||
DomainName = _shell.ReadIniEntry<string>("Document",
|
||||
"DomainName",
|
||||
iniFile),
|
||||
MachineName = _shell.ReadIniEntry<string>("Document",
|
||||
"MachineName",
|
||||
iniFile),
|
||||
UserName = _shell.ReadIniEntry<string>("Document",
|
||||
"UserName",
|
||||
iniFile)
|
||||
};
|
||||
return jobInfo;
|
||||
}
|
||||
|
||||
private void WriteJobFinishIni(string iniPath, [NotNull]IExConfig config)
|
||||
{
|
||||
const PrintStatus status = PrintStatus.Complete;
|
||||
const PrintJobStatus spoolerState = PrintJobStatus.Printed;
|
||||
|
||||
_shell.WriteIniEntry("Preconverting", "Status", status.ToIni(), iniPath);
|
||||
var pdfFile = Path.GetFileNameWithoutExtension(iniPath) + ".pdf";
|
||||
var tiffFile = Path.GetFileNameWithoutExtension(iniPath) + ".tif";
|
||||
var dir = _directoryHelper.GetOutputDirectory(config);
|
||||
pdfFile = Path.Combine(dir, pdfFile);
|
||||
tiffFile = Path.Combine(dir, tiffFile);
|
||||
_shell.WriteIniEntry("PDF", "File0", pdfFile, iniPath);
|
||||
_shell.WriteIniEntry("TIFF", "File0", tiffFile, iniPath);
|
||||
_shell.WriteIniEntry("Document", "Status", spoolerState.ToString(), iniPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
276
Common/VirtualPrinter.Agent.Lib/Misc/VirtualTcpInputPrinter.cs
Normal file
276
Common/VirtualPrinter.Agent.Lib/Misc/VirtualTcpInputPrinter.cs
Normal file
|
|
@ -0,0 +1,276 @@
|
|||
using JetBrains.Annotations;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
|
||||
using VirtualPrinter.Agent.Core;
|
||||
using VirtualPrinter.Logging;
|
||||
using VirtualPrinter.SetupDriver;
|
||||
|
||||
namespace VirtualPrinter.Agent.Lib.Misc
|
||||
{
|
||||
public class VirtualTcpInputPrinter : IVirtualPrinter
|
||||
{
|
||||
[NotNull]
|
||||
private readonly IRegistryRepository _registryRepository;
|
||||
|
||||
[NotNull]
|
||||
private readonly IJobFactory _jobFactory;
|
||||
|
||||
[NotNull]
|
||||
private readonly IJobService _jobService;
|
||||
|
||||
[NotNull]
|
||||
private readonly IVirtualPrinterLogger<VirtualTcpInputPrinter> _logger;
|
||||
|
||||
[NotNull]
|
||||
private readonly IJobProcessor _jobProcessor;
|
||||
private IDirectoryHelper _directoryHelper;
|
||||
private TcpListener _socket;
|
||||
|
||||
private FileSystemWatcher _watcher;
|
||||
|
||||
public VirtualTcpInputPrinter
|
||||
(
|
||||
[NotNull]IRegistryRepository registryRepository,
|
||||
[NotNull]IVirtualPrinterLogger<VirtualTcpInputPrinter> logger,
|
||||
[NotNull]IJobFactory jobFactory,
|
||||
[NotNull]IJobService jobService,
|
||||
[NotNull]IJobProcessor jobProcessor,
|
||||
[NotNull]IDirectoryHelper directoryHelper
|
||||
)
|
||||
{
|
||||
_registryRepository = registryRepository;
|
||||
_logger = logger;
|
||||
_jobFactory = jobFactory;
|
||||
_jobService = jobService;
|
||||
_jobProcessor = jobProcessor;
|
||||
_directoryHelper = directoryHelper;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_watcher.Dispose();
|
||||
_socket.Stop();
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
var config = GetRegistryConfig();
|
||||
|
||||
var dir = _directoryHelper.GetOutputDirectory(config);
|
||||
_watcher = new FileSystemWatcher(dir, "*.ini")
|
||||
{
|
||||
IncludeSubdirectories = false,
|
||||
NotifyFilter = NotifyFilters.LastWrite,
|
||||
EnableRaisingEvents = true
|
||||
};
|
||||
_watcher.Changed += IniFileChanged;
|
||||
_socket = new TcpListener(IPAddress.Loopback, config.PrinterPort);
|
||||
_socket.Start();
|
||||
_socket.BeginAcceptTcpClient(HandleClient, _socket);
|
||||
|
||||
LogDebug($"Waiting on {_socket.LocalEndpoint}...");
|
||||
}
|
||||
|
||||
private void HandleClient([NotNull]IAsyncResult ar)
|
||||
{
|
||||
const string printer = Defaults.PrinterName;
|
||||
IJob job;
|
||||
|
||||
var socket = (TcpListener) ar.AsyncState;
|
||||
using (var client = socket.EndAcceptTcpClient(ar))
|
||||
{
|
||||
var local = client.Client.LocalEndPoint;
|
||||
var remote = client.Client.RemoteEndPoint;
|
||||
|
||||
LogDebug($"{remote} --> {local}");
|
||||
job = _jobFactory.Create(printer, client.GetStream());
|
||||
if (job == null)
|
||||
{
|
||||
LogError("Job could not be created.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LogDebug($"Temporarily printed '{job.RawDataPath}'!");
|
||||
socket.BeginAcceptTcpClient(HandleClient, ar.AsyncState);
|
||||
|
||||
_jobService.Start(job);
|
||||
}
|
||||
|
||||
private void IniFileChanged(object sender, [NotNull]FileSystemEventArgs e)
|
||||
{
|
||||
var ini = e.FullPath;
|
||||
if (!ini.ToLowerInvariant().EndsWith(".ini"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var rawName = $"{Path.GetFileNameWithoutExtension(ini)}.ps";
|
||||
var config = GetRegistryConfig();
|
||||
var dir = _directoryHelper.GetOutputDirectory(config);
|
||||
var rawFile = Path.Combine(dir, rawName);
|
||||
var status = _jobService.ReadStatus(ini);
|
||||
|
||||
if (status == PrintStatus.Resumed)
|
||||
{
|
||||
var job = _jobService.CreateJob(ini, rawFile);
|
||||
var isJobValid = IsJobValid(job);
|
||||
|
||||
if (!isJobValid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ProcessFile(rawFile, ini);
|
||||
}
|
||||
if (status == PrintStatus.Canceled)
|
||||
{
|
||||
DeleteFiles(ini, dir, rawFile);
|
||||
}
|
||||
|
||||
var jobStatus = _jobService.ReadJobStatus(ini);
|
||||
if (jobStatus == JobStatus.Completed || jobStatus == JobStatus.Failed)
|
||||
{
|
||||
DeleteFiles(ini, dir, rawFile);
|
||||
}
|
||||
}
|
||||
|
||||
private void DeleteFiles([NotNull]string ini, [NotNull]string outputDir, [NotNull]string rawFile)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(ini))
|
||||
{
|
||||
throw new ArgumentException("Value cannot be null or whitespace.", nameof(ini));
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(outputDir))
|
||||
{
|
||||
throw new ArgumentException("Value cannot be null or whitespace.", nameof(outputDir));
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(rawFile))
|
||||
{
|
||||
throw new ArgumentException("Value cannot be null or whitespace.", nameof(rawFile));
|
||||
}
|
||||
|
||||
var pdfFile = Path.Combine(outputDir, $"{Path.GetFileNameWithoutExtension(ini)}.pdf");
|
||||
var tiffFile = Path.Combine(outputDir, $"{Path.GetFileNameWithoutExtension(ini)}.tif");
|
||||
|
||||
if (File.Exists(pdfFile) && !IsFileLocked(pdfFile))
|
||||
{
|
||||
File.Delete(pdfFile);
|
||||
}
|
||||
|
||||
if (File.Exists(tiffFile) && !IsFileLocked(tiffFile))
|
||||
{
|
||||
File.Delete(tiffFile);
|
||||
}
|
||||
|
||||
File.Delete(ini);
|
||||
File.Delete(rawFile);
|
||||
}
|
||||
|
||||
private bool IsFileLocked(string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
using(var stream = File.Open(filePath, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
stream.Close();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[NotNull]
|
||||
private IExConfig GetRegistryConfig()
|
||||
{
|
||||
return _registryRepository.GetRegistryConfig();
|
||||
}
|
||||
|
||||
private bool IsJobValid([CanBeNull]IJob job)
|
||||
{
|
||||
if (job == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(job.JobInfo.DomainName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(job.JobInfo.MachineName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(job.JobInfo.UserName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(job.SessionInfo.Sid))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ProcessFile(string filePath, string iniFile)
|
||||
{
|
||||
var thread = new Thread(obj =>
|
||||
{
|
||||
var tuple = (Tuple<string, string>) obj;
|
||||
var rawFile = tuple.Item1;
|
||||
var ini = tuple.Item2;
|
||||
|
||||
var job = _jobService.CreateJob(ini,
|
||||
rawFile);
|
||||
|
||||
try
|
||||
{
|
||||
var userConfig = _registryRepository.GetUserRegistryConfig(job.SessionInfo.Sid);
|
||||
_jobProcessor.Process(job, userConfig);
|
||||
|
||||
LogDebug($"Converted '{rawFile}'!");
|
||||
_jobService.Finish(job);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
LogError(exception,
|
||||
"Failed to process file. Job: {@job}",
|
||||
job);
|
||||
}
|
||||
});
|
||||
|
||||
thread.SetApartmentState(ApartmentState.STA);
|
||||
thread.Start(Tuple.Create(filePath, iniFile));
|
||||
}
|
||||
|
||||
private void LogError(Exception exception, string message, params object[] args)
|
||||
{
|
||||
_logger.Error(exception, message, args);
|
||||
}
|
||||
|
||||
private void LogError(string message, params object[] args)
|
||||
{
|
||||
_logger.Error(message, args);
|
||||
}
|
||||
|
||||
private void LogDebug(string message, params object[] args)
|
||||
{
|
||||
_logger.Debug(message, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
22
Common/VirtualPrinter.Agent.Lib/Model/ProgressUpdateArgs.cs
Normal file
22
Common/VirtualPrinter.Agent.Lib/Model/ProgressUpdateArgs.cs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
using VirtualPrinter.Agent.Core.Interfaces;
|
||||
|
||||
namespace VirtualPrinter.Agent.Lib.Model
|
||||
{
|
||||
public class ProgressUpdateArgs : EventArgs
|
||||
{
|
||||
public ProgressUpdateArgs([NotNull] IJob job, uint val)
|
||||
{
|
||||
Job = job;
|
||||
Value = val;
|
||||
}
|
||||
|
||||
[NotNull]
|
||||
public IJob Job { get; }
|
||||
|
||||
public uint Value { get; }
|
||||
}
|
||||
}
|
||||
32
Common/VirtualPrinter.Agent.Lib/Properties/AssemblyInfo.cs
Normal file
32
Common/VirtualPrinter.Agent.Lib/Properties/AssemblyInfo.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("VirtualPrinter.Agent.Lib")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("3d3f946d-c8dc-4518-b464-75e73cbad734")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
100
Common/VirtualPrinter.Agent.Lib/VirtualPrinter.Agent.Lib.csproj
Normal file
100
Common/VirtualPrinter.Agent.Lib/VirtualPrinter.Agent.Lib.csproj
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{94E8105F-5001-403B-B9F1-B0B0B236AD65}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>VirtualPrinter.Agent.Lib</RootNamespace>
|
||||
<AssemblyName>VirtualPrinter.Agent.Lib</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\..\Files\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<StartupObject />
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Misc\GhostScriptConverter.cs" />
|
||||
<Compile Include="Misc\JobProcessor.cs" />
|
||||
<Compile Include="Misc\JobRedirector.cs" />
|
||||
<Compile Include="Misc\Job.cs" />
|
||||
<Compile Include="Misc\JobFactory.cs" />
|
||||
<Compile Include="Misc\JobService.cs" />
|
||||
<Compile Include="Misc\VirtualTcpInputPrinter.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="VirtualPrinterService.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.IO.Compression" />
|
||||
<Reference Include="System.Printing" />
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
<Reference Include="System.ServiceModel" />
|
||||
<Reference Include="System.Transactions" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Agent\VirtualPrinter.Delivery\VirtualPrinter.Delivery.csproj">
|
||||
<Project>{74fa80b3-7cf1-4b68-8aa3-4c3d37bbe855}</Project>
|
||||
<Name>VirtualPrinter.Delivery</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Installer\VirtualPrinter.SetupDriver\VirtualPrinter.SetupDriver.csproj">
|
||||
<Project>{12402f90-a2ae-4549-9142-f90650e2082a}</Project>
|
||||
<Name>VirtualPrinter.SetupDriver</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\UI\VirtualPrinter.ProgressInfo.Core\VirtualPrinter.ProgressInfo.Core.csproj">
|
||||
<Project>{24d28558-c825-43e6-85d2-7c59f4a97698}</Project>
|
||||
<Name>VirtualPrinter.ProgressInfo.Core</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\VirtualPrinter.Agent.Core\VirtualPrinter.Agent.Core.csproj">
|
||||
<Project>{135c85eb-2116-4cc4-8ccb-b6804b9d6467}</Project>
|
||||
<Name>VirtualPrinter.Agent.Core</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\VirtualPrinter.Logging\VirtualPrinter.Logging.csproj">
|
||||
<Project>{AA25364D-22D5-44B0-86A5-6FB14C686308}</Project>
|
||||
<Name>VirtualPrinter.Logging</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\VirtualPrinter.Utils\VirtualPrinter.Utils.csproj">
|
||||
<Project>{cd1c8e9d-5335-41ac-b0c0-88fd7c7c55f3}</Project>
|
||||
<Name>VirtualPrinter.Utils</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autofac" Version="6.0.0" />
|
||||
<PackageReference Include="Cassia" Version="3.0.0-alpha.9" />
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2020.1.0" />
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="5.0.0-rc.2.20475.5" />
|
||||
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="5.0.0-rc.2.20475.5" />
|
||||
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
27
Common/VirtualPrinter.Agent.Lib/VirtualPrinterService.cs
Normal file
27
Common/VirtualPrinter.Agent.Lib/VirtualPrinterService.cs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
using JetBrains.Annotations;
|
||||
|
||||
using VirtualPrinter.Agent.Core;
|
||||
|
||||
namespace VirtualPrinter.Agent.Lib
|
||||
{
|
||||
public class VirtualPrinterService : IVirtualPrinterService
|
||||
{
|
||||
[NotNull]
|
||||
private readonly IVirtualPrinter _printer;
|
||||
|
||||
public VirtualPrinterService([NotNull]IVirtualPrinter printer)
|
||||
{
|
||||
_printer = printer;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
_printer.Init();
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
_printer.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue