[#19] Printing/Pdf: Use WinziPrint's daemon function to allow parallel usage

This commit is contained in:
2024-03-02 19:55:51 +01:00
parent 376af72700
commit 46c97089e7
4 changed files with 31 additions and 14 deletions

View File

@ -4,6 +4,7 @@
xmlns:local="clr-namespace:Elwig" xmlns:local="clr-namespace:Elwig"
xmlns:ctrl="clr-namespace:Elwig.Controls" xmlns:ctrl="clr-namespace:Elwig.Controls"
StartupUri="Windows\MainWindow.xaml" StartupUri="Windows\MainWindow.xaml"
Exit="Application_Exit"
xmlns:ui="http://schemas.modernwpf.com/2019"> xmlns:ui="http://schemas.modernwpf.com/2019">
<Application.Resources> <Application.Resources>
<ctrl:BoolToStringConverter x:Key="BoolToStarConverter" FalseValue="" TrueValue="*"/> <ctrl:BoolToStringConverter x:Key="BoolToStarConverter" FalseValue="" TrueValue="*"/>

View File

@ -143,6 +143,10 @@ namespace Elwig {
base.OnStartup(evt); base.OnStartup(evt);
} }
private async void Application_Exit(object sender, ExitEventArgs evt) {
await Pdf.Cleanup();
}
public static void SetBranch(Branch b) { public static void SetBranch(Branch b) {
SetBranch((b.ZwstId, b.Name, b.PostalDest?.AtPlz?.Plz, b.PostalDest?.AtPlz?.Ort.Name, b.Address, b.PhoneNr, b.FaxNr, b.MobileNr)); SetBranch((b.ZwstId, b.Name, b.PostalDest?.AtPlz?.Plz, b.PostalDest?.AtPlz?.Ort.Name, b.Address, b.PhoneNr, b.FaxNr, b.MobileNr));
} }

View File

@ -7,6 +7,8 @@ using System.Collections.Generic;
using System.Windows; using System.Windows;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Linq; using System.Linq;
using System.Net.Sockets;
using System.Text;
namespace Elwig.Helpers.Printing { namespace Elwig.Helpers.Printing {
public static class Pdf { public static class Pdf {
@ -14,45 +16,55 @@ namespace Elwig.Helpers.Printing {
private static readonly string PdfToPrinter = new string[] { App.ExePath } private static readonly string PdfToPrinter = new string[] { App.ExePath }
.Union(Environment.GetEnvironmentVariable("PATH")?.Split(';') ?? []) .Union(Environment.GetEnvironmentVariable("PATH")?.Split(';') ?? [])
.Select(x => Path.Combine(x, "PDFtoPrinter.exe")) .Select(x => Path.Combine(x, "PDFtoPrinter.exe"))
.Where(x => File.Exists(x)) .Where(File.Exists)
.FirstOrDefault() ?? throw new FileNotFoundException("PDFtoPrinter executable not found"); .FirstOrDefault() ?? throw new FileNotFoundException("PDFtoPrinter executable not found");
private static readonly string WinziPrint = new string[] { App.ExePath } private static readonly string WinziPrint = new string[] { App.ExePath }
.Union(Environment.GetEnvironmentVariable("PATH")?.Split(';') ?? []) .Union(Environment.GetEnvironmentVariable("PATH")?.Split(';') ?? [])
.Select(x => Path.Combine(x, "WinziPrint.exe")) .Select(x => Path.Combine(x, "WinziPrint.exe"))
.Where(x => File.Exists(x)) .Where(File.Exists)
.FirstOrDefault() ?? throw new FileNotFoundException("WiniPrint executable not found"); .FirstOrDefault() ?? throw new FileNotFoundException("WiniPrint executable not found");
private static Process? WinziPrintProc; private static Process? WinziPrintProc;
public static bool IsReady => WinziPrintProc != null; public static bool IsReady => WinziPrintProc != null;
public static async Task Init(Action? evtHandler = null) { public static Task Init(Action? evtHandler = null) {
// NOTE: If the WinziPrint daemon is already running this will succeed, but the process will fail.
// Should be no problem, as long as the daemon is not closed
var p = new Process() { StartInfo = new() { var p = new Process() { StartInfo = new() {
FileName = WinziPrint, FileName = WinziPrint,
CreateNoWindow = true, CreateNoWindow = true,
UseShellExecute = false, UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true
} }; } };
p.StartInfo.ArgumentList.Add("-p"); p.StartInfo.ArgumentList.Add("-D");
p.StartInfo.ArgumentList.Add("-e");
p.StartInfo.ArgumentList.Add("utf-8");
p.StartInfo.ArgumentList.Add("-d"); p.StartInfo.ArgumentList.Add("-d");
p.StartInfo.ArgumentList.Add(App.TempPath); p.StartInfo.ArgumentList.Add(App.TempPath);
p.StartInfo.ArgumentList.Add("-");
p.Start(); p.Start();
WinziPrintProc = p; WinziPrintProc = p;
evtHandler?.Invoke(); evtHandler?.Invoke();
return Task.CompletedTask;
}
public static Task Cleanup() {
WinziPrintProc?.Kill(true);
WinziPrintProc?.Close();
return Task.CompletedTask;
} }
public static async Task<IEnumerable<int>> Convert(string htmlPath, string pdfPath, bool doubleSided = false, IProgress<double>? progress = null) { public static async Task<IEnumerable<int>> Convert(string htmlPath, string pdfPath, bool doubleSided = false, IProgress<double>? progress = null) {
return await Convert(new string[] { htmlPath }, pdfPath, doubleSided, progress); return await Convert([htmlPath], pdfPath, doubleSided, progress);
} }
public static async Task<IEnumerable<int>> Convert(IEnumerable<string> htmlPath, string pdfPath, bool doubleSided = false, IProgress<double>? progress = null) { public static async Task<IEnumerable<int>> Convert(IEnumerable<string> htmlPath, string pdfPath, bool doubleSided = false, IProgress<double>? progress = null) {
if (WinziPrintProc == null) throw new InvalidOperationException("The WinziPrint process has not been initialized yet"); if (WinziPrintProc == null) throw new InvalidOperationException("The WinziPrint process has not been initialized yet");
progress?.Report(0.0); progress?.Report(0.0);
await WinziPrintProc.StandardInput.WriteLineAsync((doubleSided ? "-2;" : "") + $"{string.Join(';', htmlPath)};{pdfPath}"); using var client = new TcpClient("127.0.0.1", 30983);
using var stream = client.GetStream();
await stream.WriteAsync(Encoding.UTF8.GetBytes(
"-e utf-8;-p;" + (doubleSided ? "-2;" : "") +
$"{string.Join(';', htmlPath)};{pdfPath}" +
"\r\n"));
using var reader = new StreamReader(stream);
while (true) { while (true) {
var line = await WinziPrintProc.StandardOutput.ReadLineAsync() ?? throw new IOException("Invalid response from WinziPrint"); var line = await reader.ReadLineAsync() ?? throw new IOException("Invalid response from WinziPrint");
if (line.StartsWith("error:")) { if (line.StartsWith("error:")) {
throw new IOException($"WinziPrint: {line[6..].Trim()}"); throw new IOException($"WinziPrint: {line[6..].Trim()}");
} else if (line.StartsWith("progress:")) { } else if (line.StartsWith("progress:")) {

View File

@ -30,8 +30,8 @@ namespace Tests.DocumentTests {
} }
[OneTimeTearDown] [OneTimeTearDown]
public void TeardownPrinting() { public async Task TeardownPrinting() {
// no teardown needed yet await Pdf.Cleanup();
} }
} }
} }