Implemented VirtualPrinterDriver project

This commit is contained in:
Marco Batzinger 2020-10-19 17:44:50 +02:00
parent f29c84821b
commit 5c87967c3f
125 changed files with 8191 additions and 0 deletions

View file

@ -0,0 +1,98 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Printing;
using JetBrains.Annotations;
using VirtualPrinter.Logging;
using VirtualPrinter.Utils;
namespace VirtualPrinter.Delivery
{
/// <summary>
/// Redirects instructions to Ghostscript
/// </summary>
public class GhostScriptRedirector
{
private const string GsWin64 = "gswin64c.exe";
private const string GsWin32 = "gswin32c.exe";
[NotNull]
private readonly PrintQueue _queue;
public GhostScriptRedirector([NotNull]PrintQueue queue)
{
if (queue == null)
{
throw new ArgumentNullException(nameof(queue));
}
_queue = queue;
}
/// <summary>
/// Starts the Ghostscript process for the specified <paramref name="file"/>
/// </summary>
/// <param name="file">The .redirect file located in the PrinterOutput directory</param>
public void Redirect([NotNull]string file)
{
if (file == null)
{
throw new ArgumentNullException(nameof(file));
}
var logger = new VirtualPrinterLogger<GhostScriptRedirector>();
var ghostScriptExe = GetGhostScriptPath();
if (ghostScriptExe == null)
{
throw new FileNotFoundException("Can not find Ghostscript.");
}
// More details about the arguments can be find at https://www.ghostscript.com/doc/current/Use.htm
var ghostScriptArguments = $"-dPrinted -dBATCH -dNOPAUSE -dNoCancel -dNOSAFER -q -dNumCopies=1 -sDEVICE=mswinpr2 -sOutputFile=\"%printer%{ _queue.FullName}\" \"{file}\"";
logger.Info("Try to start the process {ghostScriptExe} with the following arguments: {ghostScriptArguments}.", ghostScriptExe, ghostScriptArguments);
var processStartInfo = new ProcessStartInfo
{
FileName = ghostScriptExe,
Arguments = ghostScriptArguments,
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = false,
WindowStyle = ProcessWindowStyle.Hidden
};
try
{
using(var process = Process.Start(processStartInfo))
{
process.WaitForExit();
}
}
catch (Exception exception)
{
logger.Error(exception, "Failed to start {ghostScriptExe} with the following arguments: {ghostScriptArguments}", ghostScriptExe, ghostScriptArguments);
}
}
[CanBeNull]
private string GetGhostScriptPath()
{
return GetGhostScriptPath(GsWin64) ?? GetGhostScriptPath(GsWin32);
}
[CanBeNull]
private string GetGhostScriptPath(string execName)
{
if (!new RegistryRepository().TryGetGhostscriptPath(out var path))
{
return null;
}
var ghostScriptBinPath = Path.Combine(path, "bin");
var fullPath = Path.Combine(ghostScriptBinPath, execName);
return File.Exists(fullPath) ? fullPath : null;
}
}
}

View file

@ -0,0 +1,38 @@
using System;
using JetBrains.Annotations;
using static VirtualPrinter.Delivery.Redirector;
namespace VirtualPrinter.Delivery
{
internal class Program
{
private const string RedirectCmd = "redirect";
[STAThread]
private static void Main([CanBeNull]string[] args)
{
if (args == null || args.Length < 1) {
NotUseful();
return;
}
switch (args[0]) {
case RedirectCmd: {
RedirectToPrinter(args[1], args[2]);
break;
}
default: {
NotUseful();
break;
}
}
}
private static void NotUseful()
{
throw new ArgumentNullException($"Use '{RedirectCmd}'!");
}
}
}

View file

@ -0,0 +1,18 @@
using System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("VirtualPrinter.Delivery")]
[assembly: AssemblyDescription("The delivery man for the virtual printer")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: Guid("74fa80b3-7cf1-4b68-8aa3-4c3d37bbe855")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -0,0 +1,51 @@
using System;
using System.IO;
using System.Printing;
using JetBrains.Annotations;
namespace VirtualPrinter.Delivery
{
public static class Redirector
{
public static void RedirectToPrinter([NotNull]string filePath, [NotNull]string printerName)
{
if (filePath == null)
{
throw new ArgumentNullException(nameof(filePath));
}
if (printerName == null)
{
throw new ArgumentNullException(nameof(printerName));
}
var file = Path.GetFullPath(filePath);
// e.g. "Dell C2665dnf Color MFP"
using (var localSystem = new LocalPrintServer())
{
using (var queue = localSystem.GetPrintQueueSafe(printerName))
{
if (queue != null)
{
var ghostScriptRedirector = new GhostScriptRedirector(queue);
ghostScriptRedirector.Redirect(file);
}
}
}
}
[CanBeNull]
private static PrintQueue GetPrintQueueSafe(this PrintServer server, string name)
{
try
{
return server.GetPrintQueue(name);
}
catch
{
return null;
}
}
}
}

View file

@ -0,0 +1,77 @@
<?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>{74FA80B3-7CF1-4B68-8AA3-4C3D37BBE855}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>VirtualPrinter.Delivery</RootNamespace>
<AssemblyName>delivery</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>VirtualPrinter.Delivery.Program</StartupObject>
</PropertyGroup>
<ItemGroup>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="ReachFramework" />
<Reference Include="System" />
<Reference Include="System.Printing" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="GhostScriptRedirector.cs" />
<Compile Include="Redirector.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Common\VirtualPrinter.Logging\VirtualPrinter.Logging.csproj">
<Project>{aa25364d-22d5-44b0-86a5-6fb14c686308}</Project>
<Name>VirtualPrinter.Logging</Name>
</ProjectReference>
<ProjectReference Include="..\..\Common\VirtualPrinter.Utils\VirtualPrinter.Utils.csproj">
<Project>{cd1c8e9d-5335-41ac-b0c0-88fd7c7c55f3}</Project>
<Name>VirtualPrinter.Utils</Name>
</ProjectReference>
<ProjectReference Include="..\..\Common\VirtualPrinter.Logging\VirtualPrinter.Logging.csproj">
<Project>{AA25364D-22D5-44B0-86A5-6FB14C686308}</Project>
<Name>VirtualPrinter.Logging</Name>
</ProjectReference>
<ProjectReference Include="..\..\Common\VirtualPrinter.Utils\VirtualPrinter.Utils.csproj">
<Project>{cd1c8e9d-5335-41ac-b0c0-88fd7c7c55f3}</Project>
<Name>VirtualPrinter.Utils</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="JetBrains.Annotations">
<Version>2020.1.0</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>