Implemented VirtualPrinterDriver project
This commit is contained in:
parent
f29c84821b
commit
5c87967c3f
125 changed files with 8191 additions and 0 deletions
363
.gitignore
vendored
Normal file
363
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,363 @@
|
|||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
.idea/
|
||||
41
Agent/VirtualPrinter.Agent.Console/Program.cs
Normal file
41
Agent/VirtualPrinter.Agent.Console/Program.cs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
using System;
|
||||
|
||||
using Autofac;
|
||||
|
||||
using VirtualPrinter.Agent.Autofac;
|
||||
using VirtualPrinter.Agent.Core;
|
||||
using VirtualPrinter.Logging;
|
||||
using VirtualPrinter.ProgressInfo.Autofac;
|
||||
|
||||
namespace VirtualPrinter.Agent.Console
|
||||
{
|
||||
internal static class Program
|
||||
{
|
||||
// ReSharper disable once UnusedParameter.Local
|
||||
// Start the console application to debug through the solution
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
var builder = new ContainerBuilder();
|
||||
|
||||
builder.RegisterModule(new ProgressInfoModule());
|
||||
builder.RegisterModule(new VirtualPrinterModule());
|
||||
builder.RegisterModule(new LoggerModule());
|
||||
|
||||
var container = builder.Build();
|
||||
|
||||
var service = container.Resolve<IVirtualPrinterService>();
|
||||
|
||||
service.Start();
|
||||
|
||||
System.Console.WriteLine(@"Press Ctrl + C to shutdown");
|
||||
ConsoleKeyInfo key;
|
||||
do
|
||||
{
|
||||
key = System.Console.ReadKey();
|
||||
}
|
||||
while (key.Key != ConsoleKey.C && key.Modifiers != ConsoleModifiers.Control);
|
||||
|
||||
service.Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Allgemeine Informationen über eine Assembly werden über die folgenden
|
||||
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
|
||||
// die einer Assembly zugeordnet sind.
|
||||
[assembly: AssemblyTitle("VirtualPrinter.AgentConsole")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
|
||||
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
|
||||
// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
|
||||
[assembly: Guid("3d3a379b-f9b8-466d-a04d-fd5ef948ff1c")]
|
||||
|
||||
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
|
||||
//
|
||||
// Hauptversion
|
||||
// Nebenversion
|
||||
// Buildnummer
|
||||
// Revision
|
||||
//
|
||||
// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
|
||||
// übernehmen, indem Sie "*" eingeben:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
<?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>{3D3A379B-F9B8-466D-A04D-FD5EF948FF1C}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>VirtualPrinter.Agent.Console</RootNamespace>
|
||||
<AssemblyName>VirtualPrinter.AgentConsole</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>bin\Release</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
<Reference Include="System.Core" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Common\VirtualPrinter.Agent.Autofac\VirtualPrinter.Agent.Autofac.csproj">
|
||||
<Project>{1b2f0781-82d7-4576-b936-c6a26053d6ed}</Project>
|
||||
<Name>VirtualPrinter.Agent.Autofac</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Common\VirtualPrinter.Agent.Core\VirtualPrinter.Agent.Core.csproj">
|
||||
<Project>{135c85eb-2116-4cc4-8ccb-b6804b9d6467}</Project>
|
||||
<Name>VirtualPrinter.Agent.Core</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Common\VirtualPrinter.Agent.Lib\VirtualPrinter.Agent.Lib.csproj">
|
||||
<Project>{94e8105f-5001-403b-b9f1-b0b0b236ad65}</Project>
|
||||
<Name>VirtualPrinter.Agent.Lib</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Common\VirtualPrinter.Logging\VirtualPrinter.Logging.csproj">
|
||||
<Project>{aa25364d-22d5-44b0-86a5-6fb14c686308}</Project>
|
||||
<Name>VirtualPrinter.Logging</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\UI\VirtualPrinter.ProgressInfo.Autofac\VirtualPrinter.ProgressInfo.Autofac.csproj">
|
||||
<Project>{17e2cf8a-462c-4130-9faf-f1ca5fc4e06d}</Project>
|
||||
<Name>VirtualPrinter.ProgressInfo.Autofac</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autofac" Version="6.0.0" />
|
||||
<PackageReference Include="Cassia" Version="3.0.0-alpha.9" />
|
||||
<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>
|
||||
35
Agent/VirtualPrinter.Agent.Service/Program.cs
Normal file
35
Agent/VirtualPrinter.Agent.Service/Program.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
using System.ServiceProcess;
|
||||
|
||||
using Autofac;
|
||||
|
||||
using VirtualPrinter.Agent.Autofac;
|
||||
using VirtualPrinter.Logging;
|
||||
using VirtualPrinter.ProgressInfo.Autofac;
|
||||
|
||||
namespace VirtualPrinter.Agent.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// The Windows service that is registered during an installation
|
||||
/// </summary>
|
||||
public static class Program
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
var builder = new ContainerBuilder();
|
||||
|
||||
builder.RegisterModule(new VirtualPrinterModule());
|
||||
builder.RegisterModule(new ProgressInfoModule());
|
||||
builder.RegisterModule(new LoggerModule());
|
||||
builder.RegisterType<VirtualPrinterService>().As<ServiceBase>();
|
||||
|
||||
var container = builder.Build();
|
||||
|
||||
var servicesToRun = new[]
|
||||
{
|
||||
container.Resolve<ServiceBase>()
|
||||
};
|
||||
|
||||
ServiceBase.Run(servicesToRun);
|
||||
}
|
||||
}
|
||||
}
|
||||
60
Agent/VirtualPrinter.Agent.Service/ProjectInstaller.Designer.cs
generated
Normal file
60
Agent/VirtualPrinter.Agent.Service/ProjectInstaller.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
namespace VirtualPrinter.Agent.Service
|
||||
{
|
||||
partial class ProjectInstaller
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
|
||||
this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller();
|
||||
//
|
||||
// serviceProcessInstaller1
|
||||
//
|
||||
this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
|
||||
this.serviceProcessInstaller1.Password = null;
|
||||
this.serviceProcessInstaller1.Username = null;
|
||||
//
|
||||
// serviceInstaller1
|
||||
//
|
||||
this.serviceInstaller1.ServiceName = VirtualPrinterService.PrinterServiceName;
|
||||
this.serviceInstaller1.Description = VirtualPrinterService.PrinterDescription;
|
||||
this.serviceInstaller1.ServicesDependedOn = new[] {"Spooler"};
|
||||
this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
|
||||
//
|
||||
// ProjectInstaller
|
||||
//
|
||||
this.Installers.AddRange(new System.Configuration.Install.Installer[] {
|
||||
this.serviceProcessInstaller1,
|
||||
this.serviceInstaller1});
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1;
|
||||
private System.ServiceProcess.ServiceInstaller serviceInstaller1;
|
||||
}
|
||||
}
|
||||
14
Agent/VirtualPrinter.Agent.Service/ProjectInstaller.cs
Normal file
14
Agent/VirtualPrinter.Agent.Service/ProjectInstaller.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
using System.ComponentModel;
|
||||
using System.Configuration.Install;
|
||||
|
||||
namespace VirtualPrinter.Agent.Service
|
||||
{
|
||||
[RunInstaller(true)]
|
||||
public partial class ProjectInstaller : Installer
|
||||
{
|
||||
public ProjectInstaller()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
129
Agent/VirtualPrinter.Agent.Service/ProjectInstaller.resx
Normal file
129
Agent/VirtualPrinter.Agent.Service/ProjectInstaller.resx
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="serviceProcessInstaller1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 56</value>
|
||||
</metadata>
|
||||
<metadata name="serviceInstaller1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>196, 17</value>
|
||||
</metadata>
|
||||
<metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
</root>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: AssemblyTitle("VirtualPrinter.Agent.Service")]
|
||||
[assembly: AssemblyDescription("The agent for the virtual printer")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
[assembly: Guid("8c4f0640-4628-4cea-8e31-143d68a3a70f")]
|
||||
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
|
||||
// For testing
|
||||
[assembly: InternalsVisibleTo("VirtualPrinter.Test")]
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
<?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>{8C4F0640-4628-4CEA-8E31-143D68A3A70F}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>VirtualPrinter.Agent.Service</RootNamespace>
|
||||
<AssemblyName>VPDAgent</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</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.Agent.Service.Program</StartupObject>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
<Reference Include="System.Configuration.Install" />
|
||||
<Reference Include="System.ServiceProcess" />
|
||||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ProjectInstaller.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ProjectInstaller.Designer.cs">
|
||||
<DependentUpon>ProjectInstaller.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="VirtualPrinterService.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="VirtualPrinterService.Designer.cs">
|
||||
<DependentUpon>VirtualPrinterService.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\Common\VirtualPrinter.Logging\NLog.config">
|
||||
<Link>NLog.config</Link>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="ProjectInstaller.resx">
|
||||
<DependentUpon>ProjectInstaller.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="VirtualPrinterService.resx">
|
||||
<DependentUpon>VirtualPrinterService.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Common\VirtualPrinter.Agent.Autofac\VirtualPrinter.Agent.Autofac.csproj">
|
||||
<Project>{1b2f0781-82d7-4576-b936-c6a26053d6ed}</Project>
|
||||
<Name>VirtualPrinter.Agent.Autofac</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Common\VirtualPrinter.Agent.Core\VirtualPrinter.Agent.Core.csproj">
|
||||
<Project>{135c85eb-2116-4cc4-8ccb-b6804b9d6467}</Project>
|
||||
<Name>VirtualPrinter.Agent.Core</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Common\VirtualPrinter.Agent.Lib\VirtualPrinter.Agent.Lib.csproj">
|
||||
<Project>{94e8105f-5001-403b-b9f1-b0b0b236ad65}</Project>
|
||||
<Name>VirtualPrinter.Agent.Lib</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Common\VirtualPrinter.Logging\VirtualPrinter.Logging.csproj">
|
||||
<Project>{aa25364d-22d5-44b0-86a5-6fb14c686308}</Project>
|
||||
<Name>VirtualPrinter.Logging</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\UI\VirtualPrinter.ProgressInfo.Autofac\VirtualPrinter.ProgressInfo.Autofac.csproj">
|
||||
<Project>{17e2cf8a-462c-4130-9faf-f1ca5fc4e06d}</Project>
|
||||
<Name>VirtualPrinter.ProgressInfo.Autofac</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include=".NETFramework,Version=v4.6.1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Microsoft .NET Framework 4.6.1 %28x86 and x64%29</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autofac" Version="6.0.0" />
|
||||
<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" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
40
Agent/VirtualPrinter.Agent.Service/VirtualPrinterService.Designer.cs
generated
Normal file
40
Agent/VirtualPrinter.Agent.Service/VirtualPrinterService.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
namespace VirtualPrinter.Agent.Service
|
||||
{
|
||||
partial class VirtualPrinterService
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
//
|
||||
// VirtualPrinterService
|
||||
//
|
||||
this.ServiceName = VirtualPrinterService.PrinterServiceName;
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
52
Agent/VirtualPrinter.Agent.Service/VirtualPrinterService.cs
Normal file
52
Agent/VirtualPrinter.Agent.Service/VirtualPrinterService.cs
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
using System;
|
||||
using System.ServiceProcess;
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
using VirtualPrinter.Agent.Core;
|
||||
|
||||
namespace VirtualPrinter.Agent.Service
|
||||
{
|
||||
public partial class VirtualPrinterService : ServiceBase
|
||||
{
|
||||
public const string PrinterServiceName = "VirtualPrinterService";
|
||||
public const string PrinterDescription = "Handles virtual printers";
|
||||
|
||||
[NotNull]
|
||||
private readonly IVirtualPrinterService _virtualPrinterService;
|
||||
|
||||
public VirtualPrinterService([NotNull]IVirtualPrinterService virtualPrinterService)
|
||||
{
|
||||
if (virtualPrinterService == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(virtualPrinterService));
|
||||
}
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
_virtualPrinterService = virtualPrinterService;
|
||||
}
|
||||
|
||||
protected override void OnStart(string[] args)
|
||||
{
|
||||
OnServiceStart();
|
||||
}
|
||||
|
||||
public void OnServiceStart()
|
||||
{
|
||||
// Insert additional code here to define processing.
|
||||
_virtualPrinterService.Start();
|
||||
}
|
||||
|
||||
protected override void OnStop()
|
||||
{
|
||||
OnServiceStop();
|
||||
}
|
||||
|
||||
public void OnServiceStop()
|
||||
{
|
||||
// Insert additional code here to define processing.
|
||||
_virtualPrinterService.Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
123
Agent/VirtualPrinter.Agent.Service/VirtualPrinterService.resx
Normal file
123
Agent/VirtualPrinter.Agent.Service/VirtualPrinterService.resx
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
</root>
|
||||
98
Agent/VirtualPrinter.Delivery/GhostScriptRedirector.cs
Normal file
98
Agent/VirtualPrinter.Delivery/GhostScriptRedirector.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
38
Agent/VirtualPrinter.Delivery/Program.cs
Normal file
38
Agent/VirtualPrinter.Delivery/Program.cs
Normal 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}'!");
|
||||
}
|
||||
}
|
||||
}
|
||||
18
Agent/VirtualPrinter.Delivery/Properties/AssemblyInfo.cs
Normal file
18
Agent/VirtualPrinter.Delivery/Properties/AssemblyInfo.cs
Normal 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")]
|
||||
51
Agent/VirtualPrinter.Delivery/Redirector.cs
Normal file
51
Agent/VirtualPrinter.Delivery/Redirector.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
77
Agent/VirtualPrinter.Delivery/VirtualPrinter.Delivery.csproj
Normal file
77
Agent/VirtualPrinter.Delivery/VirtualPrinter.Delivery.csproj
Normal 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>
|
||||
|
|
@ -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.Autofac")]
|
||||
[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("fc76a2af-b0db-4ec8-a6b7-dbd25d461ab5")]
|
||||
|
||||
// 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")]
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
<?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>{1B2F0781-82D7-4576-B936-C6A26053D6ED}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>VirtualPrinter.Agent.Autofac</RootNamespace>
|
||||
<AssemblyName>VirtualPrinter.Agent.Autofac</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="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="VirtualPrinterModule.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Data" />
|
||||
<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" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<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.Agent.Lib\VirtualPrinter.Agent.Lib.csproj">
|
||||
<Project>{94e8105f-5001-403b-b9f1-b0b0b236ad65}</Project>
|
||||
<Name>VirtualPrinter.Agent.Lib</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="Autofac.Extras.NLog" Version="4.0.0" />
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="5.0.0-rc.2.20475.5" />
|
||||
<PackageReference Include="NLog" Version="4.6.1" />
|
||||
<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>
|
||||
33
Common/VirtualPrinter.Agent.Autofac/VirtualPrinterModule.cs
Normal file
33
Common/VirtualPrinter.Agent.Autofac/VirtualPrinterModule.cs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
using Autofac;
|
||||
|
||||
using VirtualPrinter.Agent.Core;
|
||||
using VirtualPrinter.Agent.Lib;
|
||||
using VirtualPrinter.Agent.Lib.Misc;
|
||||
using VirtualPrinter.Utils;
|
||||
|
||||
namespace VirtualPrinter.Agent.Autofac
|
||||
{
|
||||
/// <summary>
|
||||
/// All classes to be resolved with IoC are registered here
|
||||
/// </summary>
|
||||
public class VirtualPrinterModule : Module
|
||||
{
|
||||
protected override void Load(ContainerBuilder builder)
|
||||
{
|
||||
builder.RegisterType<GhostScriptConverter>().As<IPostScriptConverter>();
|
||||
builder.RegisterType<UserRegistryConfig>().As<IUserConfig>();
|
||||
builder.RegisterType<JobService>().As<IJobService>();
|
||||
builder.RegisterType<JobFactory>().As<IJobFactory>();
|
||||
builder.RegisterType<JobProcessor>().As<IJobProcessor>();
|
||||
builder.RegisterType<Job>().As<IJob>();
|
||||
builder.RegisterType<Shell>().As<IShell>();
|
||||
builder.RegisterType<VirtualTcpInputPrinter>().As<IVirtualPrinter>();
|
||||
builder.RegisterType<RegistryConfig>().As<IExConfig>();
|
||||
builder.RegisterType<VirtualPrinterService>().As<IVirtualPrinterService>();
|
||||
builder.RegisterType<JobRedirector>().As<IJobRedirector>();
|
||||
builder.RegisterType<RegistryRepository>().As<IRegistryRepository>();
|
||||
builder.RegisterType<Shell>().As<IShell>();
|
||||
builder.RegisterType<DirectoryHelper>().As<IDirectoryHelper>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
namespace VirtualPrinter.Agent.Core.Enums
|
||||
{
|
||||
public enum IntermediateFormat
|
||||
{
|
||||
Ps,
|
||||
Xps
|
||||
}
|
||||
}
|
||||
20
Common/VirtualPrinter.Agent.Core/Interfaces/IConfig.cs
Normal file
20
Common/VirtualPrinter.Agent.Core/Interfaces/IConfig.cs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
using JetBrains.Annotations;
|
||||
|
||||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public interface IConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// The mask for the filename.
|
||||
/// </summary>
|
||||
/// <remarks>The mask can be look like {yyyy}{MM}{DD}{hh}{mm}{ss}{job05}{page03}</remarks>
|
||||
[NotNull]
|
||||
string FileNameMask { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The port of the printer.
|
||||
/// </summary>
|
||||
/// <remarks>E.g. 9101</remarks>
|
||||
short PrinterPort { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public interface IDirectoryHelper
|
||||
{
|
||||
string GetOutputDirectory(IExConfig config);
|
||||
}
|
||||
}
|
||||
36
Common/VirtualPrinter.Agent.Core/Interfaces/IExConfig.cs
Normal file
36
Common/VirtualPrinter.Agent.Core/Interfaces/IExConfig.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
using VirtualPrinter.Agent.Core.Enums;
|
||||
|
||||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public interface IExConfig : IConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Splits a preconverter into two strings.
|
||||
/// </summary>
|
||||
/// <remarks>e.g. "C:\Program Files (x86)\MySoftware\MySoftware.exe PRINT" now becomes: string 1 = "C:\Program Files (x86)\MySoftware\MySoftware.exe" and string 2 = "PRINT"</remarks>
|
||||
[NotNull]
|
||||
Tuple<string, string> ResolvedPreconverter { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Splits a postconverter into two strings.
|
||||
/// </summary>
|
||||
/// <remarks>e.g. "C:\Program Files (x86)\MySoftware\MySoftware.exe PRINTCOMPLETE" now becomes: string 1 = "C:\Program Files (x86)\MySoftware\MySoftware.exe" and string 2 = "PRINTCOMPLETE"</remarks>
|
||||
[NotNull]
|
||||
Tuple<string, string> ResolvedPostconverter { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The full path of the output directory.
|
||||
/// </summary>
|
||||
[NotNull]
|
||||
string ResolvedOutputDirectory { get; }
|
||||
|
||||
/// <summary>
|
||||
/// An intermediate format which is read by the printer or similar.
|
||||
/// </summary>
|
||||
IntermediateFormat IntermediateFormat { get; }
|
||||
}
|
||||
}
|
||||
34
Common/VirtualPrinter.Agent.Core/Interfaces/IJob.cs
Normal file
34
Common/VirtualPrinter.Agent.Core/Interfaces/IJob.cs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
using JetBrains.Annotations;
|
||||
|
||||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// The information of the job.
|
||||
/// </summary>
|
||||
public interface IJob
|
||||
{
|
||||
/// <summary>
|
||||
/// The path to the file containing the data.
|
||||
/// </summary>
|
||||
[NotNull]
|
||||
string RawDataPath { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The path to the ini file.
|
||||
/// </summary>
|
||||
[NotNull]
|
||||
string IniDataPath { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Several job infos.
|
||||
/// </summary>
|
||||
[NotNull]
|
||||
IJobInfo JobInfo { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Information about the session.
|
||||
/// </summary>
|
||||
[NotNull]
|
||||
ISessionInfo SessionInfo { get; }
|
||||
}
|
||||
}
|
||||
15
Common/VirtualPrinter.Agent.Core/Interfaces/IJobFactory.cs
Normal file
15
Common/VirtualPrinter.Agent.Core/Interfaces/IJobFactory.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
using System.IO;
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public interface IJobFactory
|
||||
{
|
||||
[CanBeNull]
|
||||
IJob Create([NotNull]string printerName, [NotNull]Stream stream);
|
||||
|
||||
[NotNull]
|
||||
IJob Create([NotNull]string iniPath, [NotNull]string rawPath, IJobInfo jobInfo, ISessionInfo sessionInfo);
|
||||
}
|
||||
}
|
||||
15
Common/VirtualPrinter.Agent.Core/Interfaces/IJobInfo.cs
Normal file
15
Common/VirtualPrinter.Agent.Core/Interfaces/IJobInfo.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
using System.Printing;
|
||||
|
||||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public interface IJobInfo
|
||||
{
|
||||
int JobId { get; set; }
|
||||
string Name { get; set; }
|
||||
string DomainName { get; set; }
|
||||
string MachineName { get; set; }
|
||||
string UserName { get; set; }
|
||||
PrintJobStatus Status { get; set; }
|
||||
string DeviceName { get; set; }
|
||||
}
|
||||
}
|
||||
18
Common/VirtualPrinter.Agent.Core/Interfaces/IJobProcessor.cs
Normal file
18
Common/VirtualPrinter.Agent.Core/Interfaces/IJobProcessor.cs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
using System;
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public interface IJobProcessor
|
||||
{
|
||||
/// <summary>
|
||||
/// Processes an <see cref="IJob"/> passed to it with the information from the <see cref="IUserConfig"/>.
|
||||
/// </summary>
|
||||
/// <param name="job"></param>
|
||||
/// <param name="userConfig"></param>
|
||||
/// <exception cref="ArgumentNullException">Throws when the <param name="job">job</param> or the <param name="userConfig"> is null.</param></exception>
|
||||
/// <exception cref="PostScriptConversionException">The job cannot be converted. There is no redirect to a printer. Will not be thrown.</exception>
|
||||
void Process([NotNull]IJob job, [NotNull]IUserConfig userConfig);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public interface IJobRedirector
|
||||
{
|
||||
/// <summary>
|
||||
/// Redirects the information from the <param name="job">job</param> and the <param name="userConfig">config</param> to an Process to be executed.
|
||||
/// </summary>
|
||||
/// <param name="job"></param>
|
||||
/// <param name="userConfig"></param>
|
||||
/// <exception cref="ArgumentNullException">Throws when the <see cref="IJob"/> or the <see cref="IUserConfig"/> is null.</exception>
|
||||
void Redirect([NotNull]IJob job, [NotNull]IUserConfig userConfig);
|
||||
}
|
||||
}
|
||||
47
Common/VirtualPrinter.Agent.Core/Interfaces/IJobService.cs
Normal file
47
Common/VirtualPrinter.Agent.Core/Interfaces/IJobService.cs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
using System;
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public interface IJobService
|
||||
{
|
||||
/// <summary>
|
||||
/// Starts the <see cref="IJob"/> in a new Process.
|
||||
/// </summary>
|
||||
/// <param name="job"></param>
|
||||
/// <exception cref="ArgumentNullException">Throws when the <see cref="IJob"/> is null.</exception>
|
||||
void Start([NotNull]IJob job);
|
||||
|
||||
/// <summary>
|
||||
/// Creates an new <see cref="IJob"/> from the <param name="iniPath">ini file</param> and the <param name="rawPath">raw path</param>.
|
||||
/// </summary>
|
||||
/// <param name="iniPath"></param>
|
||||
/// <param name="rawPath"></param>
|
||||
/// <returns>An new <see cref="IJob"/> object.</returns>
|
||||
/// <exception cref="ArgumentException">Throws when the <paramref name="iniPath"/> or the <paramref name="rawPath"/> is null or empty.</exception>
|
||||
[NotNull]
|
||||
IJob CreateJob([NotNull]string iniPath, [NotNull]string rawPath);
|
||||
|
||||
/// <summary>
|
||||
/// Reads the <see cref="PrintStatus"/> from the <paramref name="iniPath"/>
|
||||
/// </summary>
|
||||
/// <param name="iniPath"></param>
|
||||
/// <returns>A <see cref="PrintStatus"/></returns>
|
||||
/// <exception cref="ArgumentException">Throws when the <paramref name="iniPath"/> is null or empty.</exception>
|
||||
PrintStatus ReadStatus([NotNull]string iniPath);
|
||||
|
||||
/// <summary>
|
||||
/// Starts a new process to finish the <see cref="IJob"/>.
|
||||
/// </summary>
|
||||
/// <param name="job"></param>
|
||||
void Finish([NotNull]IJob job);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="JobStatus"/> from the ini file.
|
||||
/// </summary>
|
||||
/// <param name="iniPath">The path to the ini file</param>
|
||||
/// <returns><see cref="JobStatus"/></returns>
|
||||
JobStatus ReadJobStatus(string iniPath);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
|
||||
using VirtualPrinter.Agent.Lib.Model;
|
||||
|
||||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public interface IPostScriptConverter
|
||||
{
|
||||
event EventHandler<IJob> ProgressInitialized;
|
||||
event EventHandler<IJob> ProgressFinished;
|
||||
event EventHandler<ProgressUpdateArgs> ProgressUpdate;
|
||||
|
||||
void Convert(IJob job, string target, PostScriptRenderOptions options);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
using JetBrains.Annotations;
|
||||
|
||||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public interface IRegistryRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// Try to get the ghostscript path from.
|
||||
/// </summary>
|
||||
/// <returns>True if the path exists.</returns>
|
||||
[ContractAnnotation("=>true,path:notnull; =>false,path:null")]
|
||||
bool TryGetGhostscriptPath(out string path);
|
||||
|
||||
/// <summary>
|
||||
/// Get the <see cref="IExConfig"/> from the registry.
|
||||
/// </summary>
|
||||
/// <returns>The configuration that was read from the registry in HKEY_LOCAL_MACHINE\SOFTWARE.</returns>
|
||||
[NotNull]
|
||||
IExConfig GetRegistryConfig();
|
||||
|
||||
/// <summary>
|
||||
/// Get the <see cref="IUserConfig"/> from the registry.
|
||||
/// </summary>
|
||||
/// <param name="sid">The security identifier with which each Windows user can be clearly identified in the network.</param>
|
||||
/// <returns>The configuration that was read from the registry in HKEY_USERS</returns>
|
||||
[NotNull]
|
||||
IUserConfig GetUserRegistryConfig([NotNull]string sid);
|
||||
}
|
||||
}
|
||||
11
Common/VirtualPrinter.Agent.Core/Interfaces/ISessionInfo.cs
Normal file
11
Common/VirtualPrinter.Agent.Core/Interfaces/ISessionInfo.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public interface ISessionInfo
|
||||
{
|
||||
int Id { get; set; }
|
||||
|
||||
string Desktop { get; set; }
|
||||
|
||||
string Sid { get; set; }
|
||||
}
|
||||
}
|
||||
16
Common/VirtualPrinter.Agent.Core/Interfaces/IShell.cs
Normal file
16
Common/VirtualPrinter.Agent.Core/Interfaces/IShell.cs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
using JetBrains.Annotations;
|
||||
|
||||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public interface IShell
|
||||
{
|
||||
void WriteIniEntry(string section, string key, string value, string iniFilePath);
|
||||
|
||||
[NotNull]
|
||||
T ReadIniEntry<T>(string section, string key, string iniFilePath);
|
||||
|
||||
void Execute(IJobInfo job, ISessionInfo session, string exe, string args);
|
||||
|
||||
bool FileExists([NotNull]string path);
|
||||
}
|
||||
}
|
||||
26
Common/VirtualPrinter.Agent.Core/Interfaces/IUserConfig.cs
Normal file
26
Common/VirtualPrinter.Agent.Core/Interfaces/IUserConfig.cs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
using JetBrains.Annotations;
|
||||
|
||||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public interface IUserConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// The printer stored in the registry.
|
||||
/// </summary>
|
||||
[CanBeNull]
|
||||
string RedirectPrinter { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The DPI value stored in the registry.
|
||||
/// </summary>
|
||||
/// <remarks>Initial value is null.</remarks>
|
||||
double? UserRenderDpi { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The format that you choose on your client side stored in the registry.
|
||||
/// </summary>
|
||||
/// <remarks>Intital value is PDF</remarks>
|
||||
[NotNull]
|
||||
string Format { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
|
||||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public interface IVirtualPrinter : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Initialize the virtual printer.
|
||||
/// </summary>
|
||||
void Init();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public interface IVirtualPrinterService
|
||||
{
|
||||
void Start();
|
||||
void Stop();
|
||||
}
|
||||
}
|
||||
9
Common/VirtualPrinter.Agent.Core/Interfaces/JobStatus.cs
Normal file
9
Common/VirtualPrinter.Agent.Core/Interfaces/JobStatus.cs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public enum JobStatus
|
||||
{
|
||||
Completed,
|
||||
Failed,
|
||||
InProgress
|
||||
}
|
||||
}
|
||||
15
Common/VirtualPrinter.Agent.Core/Model/JobInfo.cs
Normal file
15
Common/VirtualPrinter.Agent.Core/Model/JobInfo.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
using System.Printing;
|
||||
|
||||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public struct JobInfo : IJobInfo
|
||||
{
|
||||
public int JobId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string DomainName { get; set; }
|
||||
public string MachineName { get; set; }
|
||||
public string UserName { get; set; }
|
||||
public PrintJobStatus Status { get; set; }
|
||||
public string DeviceName { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
|
||||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public class PostScriptConversionException : Exception
|
||||
{
|
||||
public PostScriptConversionException()
|
||||
{
|
||||
}
|
||||
|
||||
public PostScriptConversionException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public PostScriptConversionException(string message, Exception inner) : base(message, inner)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public struct PostScriptRenderOptions
|
||||
{
|
||||
public double? UserRenderDpi { get; set; }
|
||||
public PostScriptRenderPdfOptions PdfOptions { get; set; }
|
||||
public PostScriptRenderTiffOptions TiffOptions { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public struct PostScriptRenderPdfOptions
|
||||
{
|
||||
public bool Enabled { set; get; }
|
||||
public bool Archivable { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public struct PostScriptRenderTiffOptions
|
||||
{
|
||||
public bool Enabled { set; get; }
|
||||
}
|
||||
}
|
||||
13
Common/VirtualPrinter.Agent.Core/Model/PrintExts.cs
Normal file
13
Common/VirtualPrinter.Agent.Core/Model/PrintExts.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
using JetBrains.Annotations;
|
||||
|
||||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public static class PrintExts
|
||||
{
|
||||
[NotNull]
|
||||
public static string ToIni(this PrintStatus status)
|
||||
{
|
||||
return status.ToString().ToLowerInvariant();
|
||||
}
|
||||
}
|
||||
}
|
||||
15
Common/VirtualPrinter.Agent.Core/Model/PrintStatus.cs
Normal file
15
Common/VirtualPrinter.Agent.Core/Model/PrintStatus.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public enum PrintStatus
|
||||
{
|
||||
Undefined = 0,
|
||||
|
||||
Paused,
|
||||
|
||||
Resumed,
|
||||
|
||||
Complete,
|
||||
|
||||
Canceled
|
||||
}
|
||||
}
|
||||
22
Common/VirtualPrinter.Agent.Core/Model/ProgressUpdateArgs.cs
Normal file
22
Common/VirtualPrinter.Agent.Core/Model/ProgressUpdateArgs.cs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
using VirtualPrinter.Agent.Core;
|
||||
|
||||
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; }
|
||||
}
|
||||
}
|
||||
49
Common/VirtualPrinter.Agent.Core/Model/RegistryConfig.cs
Normal file
49
Common/VirtualPrinter.Agent.Core/Model/RegistryConfig.cs
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
using VirtualPrinter.Agent.Core.Enums;
|
||||
|
||||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public class RegistryConfig : IExConfig
|
||||
{
|
||||
public string Postconverter { get; set; }
|
||||
|
||||
public string Preconverter { get; set; }
|
||||
|
||||
public string OutputDirectory { get; set; }
|
||||
|
||||
public string FileNameMask { get; set; }
|
||||
|
||||
public short PrinterPort { get; set; }
|
||||
|
||||
public Tuple<string, string> ResolvedPreconverter
|
||||
{
|
||||
get { return GetResolvedArgs(Preconverter); }
|
||||
}
|
||||
|
||||
public Tuple<string, string> ResolvedPostconverter
|
||||
{
|
||||
get { return GetResolvedArgs(Postconverter); }
|
||||
}
|
||||
|
||||
public string ResolvedOutputDirectory
|
||||
{
|
||||
get { return string.IsNullOrWhiteSpace(OutputDirectory) ? "" : Path.GetFullPath(OutputDirectory); }
|
||||
}
|
||||
|
||||
public IntermediateFormat IntermediateFormat { get; set; }
|
||||
|
||||
[NotNull]
|
||||
private static Tuple<string, string> GetResolvedArgs([NotNull]string text)
|
||||
{
|
||||
const string ending = ".exe";
|
||||
var parts = text.Split(new[] { ending }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
return Tuple.Create(Path.GetFullPath(parts.First() + ending), parts.Last().Trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Common/VirtualPrinter.Agent.Core/Model/SessionInfo.cs
Normal file
11
Common/VirtualPrinter.Agent.Core/Model/SessionInfo.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public struct SessionInfo : ISessionInfo
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Desktop { get; set; }
|
||||
|
||||
public string Sid { get; set; }
|
||||
}
|
||||
}
|
||||
13
Common/VirtualPrinter.Agent.Core/Model/UserRegistryConfig.cs
Normal file
13
Common/VirtualPrinter.Agent.Core/Model/UserRegistryConfig.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
namespace VirtualPrinter.Agent.Core
|
||||
{
|
||||
public class UserRegistryConfig : IUserConfig
|
||||
{
|
||||
public bool RedirectEnabled { get; set; }
|
||||
|
||||
public string RedirectPrinter { get; set; }
|
||||
|
||||
public double? UserRenderDpi { get; set; }
|
||||
|
||||
public string Format { get; set; }
|
||||
}
|
||||
}
|
||||
35
Common/VirtualPrinter.Agent.Core/Properties/AssemblyInfo.cs
Normal file
35
Common/VirtualPrinter.Agent.Core/Properties/AssemblyInfo.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Allgemeine Informationen über eine Assembly werden über die folgenden
|
||||
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
|
||||
// die einer Assembly zugeordnet sind.
|
||||
[assembly: AssemblyTitle("VirtualPrinter.Agent.Core")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
|
||||
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
|
||||
// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
|
||||
[assembly: Guid("135c85eb-2116-4cc4-8ccb-b6804b9d6467")]
|
||||
|
||||
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
|
||||
//
|
||||
// Hauptversion
|
||||
// Nebenversion
|
||||
// Buildnummer
|
||||
// Revision
|
||||
//
|
||||
// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
|
||||
// indem Sie "*" wie unten gezeigt eingeben:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
|
|
@ -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>{135C85EB-2116-4CC4-8CCB-B6804B9D6467}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>VirtualPrinter.Agent.Core</RootNamespace>
|
||||
<AssemblyName>VirtualPrinter.Agent.Core</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<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' ">
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\..\Files\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="ReachFramework" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Printing" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Enums\IntermediateFormat.cs" />
|
||||
<Compile Include="Interfaces\IDirectoryHelper.cs" />
|
||||
<Compile Include="Interfaces\IConfig.cs" />
|
||||
<Compile Include="Interfaces\IExConfig.cs" />
|
||||
<Compile Include="Interfaces\IJob.cs" />
|
||||
<Compile Include="Interfaces\IJobFactory.cs" />
|
||||
<Compile Include="Interfaces\IJobInfo.cs" />
|
||||
<Compile Include="Interfaces\IJobProcessor.cs" />
|
||||
<Compile Include="Interfaces\IJobRedirector.cs" />
|
||||
<Compile Include="Interfaces\IJobService.cs" />
|
||||
<Compile Include="Interfaces\IPostScriptConverter.cs" />
|
||||
<Compile Include="Interfaces\IRegistryRepository.cs" />
|
||||
<Compile Include="Interfaces\ISessionInfo.cs" />
|
||||
<Compile Include="Interfaces\IShell.cs" />
|
||||
<Compile Include="Interfaces\IUserConfig.cs" />
|
||||
<Compile Include="Interfaces\IVirtualPrinter.cs" />
|
||||
<Compile Include="Interfaces\IVirtualPrinterService.cs" />
|
||||
<Compile Include="Interfaces\JobStatus.cs" />
|
||||
<Compile Include="Model\JobInfo.cs" />
|
||||
<Compile Include="Model\PostScriptConversionException.cs" />
|
||||
<Compile Include="Model\PostScriptRenderOptions.cs" />
|
||||
<Compile Include="Model\PostScriptRenderPdfOptions.cs" />
|
||||
<Compile Include="Model\PostScriptRenderTiffOptions.cs" />
|
||||
<Compile Include="Model\ProgressUpdateArgs.cs" />
|
||||
<Compile Include="Model\RegistryConfig.cs" />
|
||||
<Compile Include="Model\UserRegistryConfig.cs" />
|
||||
<Compile Include="Model\PrintExts.cs" />
|
||||
<Compile Include="Model\PrintStatus.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Model\SessionInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2020.1.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
81
Common/VirtualPrinter.Logging/IVirtualPrinterLogger.cs
Normal file
81
Common/VirtualPrinter.Logging/IVirtualPrinterLogger.cs
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
using System;
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace VirtualPrinter.Logging
|
||||
{
|
||||
// ReSharper disable once UnusedTypeParameter
|
||||
public interface IVirtualPrinterLogger<out T> : IVirtualPrinterLogger
|
||||
{ }
|
||||
|
||||
public interface IVirtualPrinterLogger
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name of the logger.
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A value of true if logging is enabled for the Debug level, otherwise it returns false.
|
||||
/// </summary>
|
||||
bool IsDebugEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A value of true if logging is enabled for the Trace level, otherwise it returns false.
|
||||
/// </summary>
|
||||
bool IsTraceEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Writes the exception at the <c>Error</c> level.
|
||||
/// </summary>
|
||||
/// <param name="exception">An exception to be logged.</param>
|
||||
void Error([CanBeNull]Exception exception);
|
||||
|
||||
/// <summary>
|
||||
/// Writes the diagnostic message and exception at the <c>Error</c> level.
|
||||
/// </summary>
|
||||
/// <param name="exception">An exception to be logged.</param>
|
||||
/// <param name="message">A <see langword="string" /> to be written.</param>
|
||||
/// <param name="args">Arguments to format.</param>
|
||||
void Error([CanBeNull]Exception exception, [CanBeNull]string message, [CanBeNull, ItemCanBeNull]params object[] args);
|
||||
|
||||
/// <summary>
|
||||
/// Something failed; application may or may not continue
|
||||
/// Writes the diagnostic message and exception at the <c>Error</c> level.
|
||||
/// </summary>
|
||||
/// <param name="message">A <see langword="string" /> to be written.</param>
|
||||
/// <param name="args">Arguments to format.</param>
|
||||
void Error([CanBeNull]string message, [CanBeNull, ItemCanBeNull]params object[] args);
|
||||
|
||||
/// <summary>
|
||||
/// Something unexpected; application will continue
|
||||
/// Writes the diagnostic message at the <c>Warn</c> level using the specified parameters.
|
||||
/// </summary>
|
||||
/// <param name="message">A <see langword="string" /> containing format items.</param>
|
||||
/// <param name="args">Arguments to format.</param>
|
||||
void Warn([CanBeNull]string message, [CanBeNull, ItemCanBeNull]params object[] args);
|
||||
|
||||
/// <summary>
|
||||
/// Normal behavior like mail sent, user updated profile etc.
|
||||
/// Writes the diagnostic message at the <c>Info</c> level using the specified parameters.
|
||||
/// </summary>
|
||||
/// <param name="message">A <see langword="string" /> containing format items.</param>
|
||||
/// <param name="args">Arguments to format.</param>
|
||||
void Info([CanBeNull]string message, [CanBeNull, ItemCanBeNull]params object[] args);
|
||||
|
||||
/// <summary>
|
||||
/// For debugging; executed query, user authenticated, session expired
|
||||
/// Writes the diagnostic message at the <c>Debug</c> level using the specified parameters.
|
||||
/// </summary>
|
||||
/// <param name="message">A <see langword="string" /> containing format items.</param>
|
||||
/// <param name="args">Arguments to format.</param>
|
||||
void Debug([CanBeNull]string message, [CanBeNull, ItemCanBeNull]params object[] args);
|
||||
|
||||
/// <summary>
|
||||
/// Writes the diagnostic message at the <c>Trace</c> level using the specified parameters.
|
||||
/// </summary>
|
||||
/// <param name="message">A <see langword="string" /> containing format items.</param>
|
||||
/// <param name="args">Arguments to format.</param>
|
||||
void Trace([CanBeNull]string message, [CanBeNull, ItemCanBeNull]params object[] args);
|
||||
}
|
||||
}
|
||||
17
Common/VirtualPrinter.Logging/LoggerModule.cs
Normal file
17
Common/VirtualPrinter.Logging/LoggerModule.cs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
using Autofac;
|
||||
using Autofac.Extras.NLog;
|
||||
|
||||
namespace VirtualPrinter.Logging
|
||||
{
|
||||
public class LoggerModule : Module
|
||||
{
|
||||
protected override void Load(ContainerBuilder builder)
|
||||
{
|
||||
builder.RegisterModule<NLogModule>();
|
||||
builder.RegisterInstance(NLog.LogManager.GetCurrentClassLogger()).As<NLog.ILogger>().SingleInstance();
|
||||
builder.RegisterGeneric(typeof(VirtualPrinterLogger<>))
|
||||
.As(typeof(IVirtualPrinterLogger<>))
|
||||
.SingleInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
25
Common/VirtualPrinter.Logging/NLog.config
Normal file
25
Common/VirtualPrinter.Logging/NLog.config
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
|
||||
autoReload="true"
|
||||
throwExceptions="false"
|
||||
internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">
|
||||
|
||||
<variable name="log_title" value="${processname}"/>
|
||||
|
||||
<targets>
|
||||
<target name="console" xsi:type="ColoredConsole" layout="${longdate} ${level} ${message} ${exception:format=ToString}"/>
|
||||
<target xsi:type="EventLog"
|
||||
name="eventlog"
|
||||
log ="Application"
|
||||
source="${var:log_title}"
|
||||
layout="${message}${newline}${exception:format=ToString}">
|
||||
</target>
|
||||
</targets>
|
||||
|
||||
<rules>
|
||||
<logger name="*" minlevel="Debug" writeTo="console" />
|
||||
<logger name="*" minlevel="Info" writeTo="eventlog" />
|
||||
</rules>
|
||||
</nlog>
|
||||
35
Common/VirtualPrinter.Logging/Properties/AssemblyInfo.cs
Normal file
35
Common/VirtualPrinter.Logging/Properties/AssemblyInfo.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
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.Logging")]
|
||||
[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("aa25364d-22d5-44b0-86a5-6fb14c686308")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
71
Common/VirtualPrinter.Logging/VirtualPrinter.Logging.csproj
Normal file
71
Common/VirtualPrinter.Logging/VirtualPrinter.Logging.csproj
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
<?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>{AA25364D-22D5-44B0-86A5-6FB14C686308}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>VirtualPrinter.Logging</RootNamespace>
|
||||
<AssemblyName>VirtualPrinter.Logging</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<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' ">
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\..\Files</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.IO.Compression" />
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
<Reference Include="System.ServiceModel" />
|
||||
<Reference Include="System.Transactions" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="IVirtualPrinterLogger.cs" />
|
||||
<Compile Include="LoggerModule.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="VirtualPrinterLogger.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="NLog.config">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autofac" Version="6.0.0" />
|
||||
<PackageReference Include="Autofac.Extras.NLog" Version="4.0.0" />
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2020.1.0" />
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="5.0.0-rc.2.20475.5" />
|
||||
<PackageReference Include="NLog" Version="4.6.1" />
|
||||
<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>
|
||||
103
Common/VirtualPrinter.Logging/VirtualPrinterLogger.cs
Normal file
103
Common/VirtualPrinter.Logging/VirtualPrinterLogger.cs
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
using System;
|
||||
using System.CodeDom;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.IO;
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
using NLog;
|
||||
|
||||
namespace VirtualPrinter.Logging
|
||||
{
|
||||
public class VirtualPrinterLogger<T> : VirtualPrinterLogger, IVirtualPrinterLogger<T>
|
||||
{
|
||||
public VirtualPrinterLogger() : base(ReadableTypeName.Generate(typeof(T)))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public static class ReadableTypeName
|
||||
{
|
||||
[NotNull]
|
||||
public static string Generate([NotNull]Type type)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(type));
|
||||
}
|
||||
|
||||
var provider = CodeDomProvider.CreateProvider("C#");
|
||||
var typeReferenceExpression = new CodeTypeReferenceExpression(type);
|
||||
using (var writer = new StringWriter())
|
||||
{
|
||||
provider.GenerateCodeFromExpression(typeReferenceExpression, writer, new CodeGeneratorOptions());
|
||||
return writer.GetStringBuilder().ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class VirtualPrinterLogger : IVirtualPrinterLogger
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public VirtualPrinterLogger([NotNull]string loggerName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(loggerName))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(loggerName));
|
||||
}
|
||||
|
||||
_logger = LogManager.GetLogger(loggerName);
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return _logger.Name; }
|
||||
}
|
||||
|
||||
public bool IsDebugEnabled
|
||||
{
|
||||
get { return _logger.IsDebugEnabled; }
|
||||
}
|
||||
|
||||
public bool IsTraceEnabled
|
||||
{
|
||||
get { return _logger.IsTraceEnabled; }
|
||||
}
|
||||
|
||||
public void Error(Exception exception)
|
||||
{
|
||||
_logger.Error(exception);
|
||||
}
|
||||
|
||||
public void Error(Exception exception, string message, params object[] args)
|
||||
{
|
||||
_logger.Error(exception, message, args);
|
||||
}
|
||||
|
||||
public void Error(string message, params object[] args)
|
||||
{
|
||||
_logger.Error(message, args);
|
||||
}
|
||||
|
||||
public void Warn(string message, params object[] args)
|
||||
{
|
||||
_logger.Warn(message, args);
|
||||
}
|
||||
|
||||
public void Info(string message, params object[] args)
|
||||
{
|
||||
_logger.Info(message, args);
|
||||
}
|
||||
|
||||
public void Debug(string message, params object[] args)
|
||||
{
|
||||
_logger.Debug(message, args);
|
||||
}
|
||||
|
||||
public void Trace(string message, params object[] args)
|
||||
{
|
||||
_logger.Trace(message, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
51
Common/VirtualPrinter.Utils/Consts.cs
Normal file
51
Common/VirtualPrinter.Utils/Consts.cs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
namespace VirtualPrinter.Utils
|
||||
{
|
||||
public struct Files
|
||||
{
|
||||
public const string FILES = @"Files";
|
||||
public const string PRINTER_SERVICE_EXE = "VPDAgent.exe";
|
||||
public const string SETUP_DRIVER_EXE = "setupdrv.exe";
|
||||
public const string AGENT_PROGRESS_EXE = "VPDAgentProgress.exe";
|
||||
public const string DILIVERY_EXE = "delivery.exe";
|
||||
public const string LICENCE_FILE = "";
|
||||
public const string PRE_CONVERTER = @"C:\Program Files (x86)\MyPreConverter.exe ARG";
|
||||
public const string POST_CONVERTER = @"C:\Program Files (x86)\MyPostConverter.exe ARG";
|
||||
}
|
||||
|
||||
public struct Keys
|
||||
{
|
||||
public const string PRINTER_DRIVER_KEY32 = @"SOFTWARE\vpd\PrinterDriver";
|
||||
public const string PRINTER_DRIVER_KEY64 = @"SOFTWARE\Wow6432Node\vpd\PrinterDriver";
|
||||
public const string POSTCONVERTER_KEY = @"Application\Postconverter";
|
||||
public const string PRECONVERTER_KEY = @"Application\Preconverter";
|
||||
public const string CONVERTER_KEY = @"Converter";
|
||||
public const string CONVERTER_PDF_KEY = CONVERTER_KEY + @"\PDF";
|
||||
public const string CONVERTER_TIFF_KEY = CONVERTER_KEY + @"\TIFF";
|
||||
public const string CONVERTER_REDIRECT_KEY = CONVERTER_KEY + @"\Redirect";
|
||||
}
|
||||
|
||||
public struct KeyNames
|
||||
{
|
||||
public const string EXECUTABLE_FILE = "Executable File";
|
||||
public const string INSTALLATION_DIR = "Installation Directory";
|
||||
public const string THREADS = "Threads";
|
||||
public const string SHOW_PROGRESS = "Show Progress";
|
||||
public const string PAGES_PER_SHEET = "Pages per Sheet";
|
||||
public const string FILE_NAME_MASK = "File name mask";
|
||||
public const string OUTPUT_DIR = "Output Directory";
|
||||
public const string ENABLED = "Enabled";
|
||||
public const string MULTIPAGE = "Multipage";
|
||||
public const string PRODUCE_PDFA = "Produce PDFA";
|
||||
public const string ALLOW_PRINTING = "Allow printing";
|
||||
public const string ALLOW_COPYING = "Allow printing";
|
||||
public const string SUBSETTING = "Subsetting";
|
||||
public const string QUALITY = "Image Quality";
|
||||
public const string BITS_PIXEL = "Bits per pixel";
|
||||
public const string COMPRESSION = "Compression";
|
||||
public const string SERVER_PORT = "Server port";
|
||||
public const string RENDER_DPI = "RENDER: DPI";
|
||||
public const string FORMAT = "Intermediate Format";
|
||||
public const string PRINT_FORMAT = "Format";
|
||||
public const string PRINTER = "Printer";
|
||||
}
|
||||
}
|
||||
24
Common/VirtualPrinter.Utils/DirectoryHelper.cs
Normal file
24
Common/VirtualPrinter.Utils/DirectoryHelper.cs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
using System.IO;
|
||||
|
||||
using VirtualPrinter.Agent.Core;
|
||||
|
||||
namespace VirtualPrinter.Utils
|
||||
{
|
||||
public class DirectoryHelper : IDirectoryHelper
|
||||
{
|
||||
public string GetOutputDirectory(IExConfig config)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(config.ResolvedOutputDirectory))
|
||||
{
|
||||
var outputDir = Path.Combine(Path.GetTempPath(), "PrinterOutput");
|
||||
if (!Directory.Exists(outputDir))
|
||||
{
|
||||
Directory.CreateDirectory(outputDir);
|
||||
}
|
||||
return outputDir;
|
||||
}
|
||||
|
||||
return config.ResolvedOutputDirectory;
|
||||
}
|
||||
}
|
||||
}
|
||||
35
Common/VirtualPrinter.Utils/Properties/AssemblyInfo.cs
Normal file
35
Common/VirtualPrinter.Utils/Properties/AssemblyInfo.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
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.Utils")]
|
||||
[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("cd1c8e9d-5335-41ac-b0c0-88fd7c7c55f3")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
170
Common/VirtualPrinter.Utils/RegistryRepository.cs
Normal file
170
Common/VirtualPrinter.Utils/RegistryRepository.cs
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
using Microsoft.Win32;
|
||||
|
||||
using VirtualPrinter.Agent.Core;
|
||||
using VirtualPrinter.Agent.Core.Enums;
|
||||
|
||||
namespace VirtualPrinter.Utils
|
||||
{
|
||||
public class RegistryRepository : IRegistryRepository
|
||||
{
|
||||
private const short DefaultServerPort = 9101;
|
||||
|
||||
public bool TryGetGhostscriptPath(out string path)
|
||||
{
|
||||
path = null;
|
||||
|
||||
try
|
||||
{
|
||||
var regView = GetRegistryView();
|
||||
|
||||
using(var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, regView))
|
||||
{
|
||||
const string gsSubKey = @"SOFTWARE\GPL Ghostscript";
|
||||
using(var ghostscript = baseKey.OpenSubKey(gsSubKey))
|
||||
{
|
||||
CheckForNull(ghostscript, gsSubKey);
|
||||
var subKeys = ghostscript.GetSubKeyNames();
|
||||
|
||||
var lastSubKey = subKeys.Last();
|
||||
using(var subKey = ghostscript.OpenSubKey(lastSubKey))
|
||||
{
|
||||
CheckForNull(subKey, lastSubKey);
|
||||
path = subKey.GetValue("GS_LIB").ToString().Split(';').FirstOrDefault();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
path = Directory.GetParent(path).FullName;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Console.WriteLine(exception);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public IExConfig GetRegistryConfig()
|
||||
{
|
||||
var regView = GetRegistryView();
|
||||
var subKey = GetSubKey();
|
||||
var registryConfig = new RegistryConfig();
|
||||
|
||||
using (var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, regView))
|
||||
{
|
||||
using (var driver = baseKey.OpenSubKey(subKey))
|
||||
{
|
||||
CheckForNull(driver, subKey);
|
||||
|
||||
using(var key = driver.OpenSubKey(Keys.POSTCONVERTER_KEY))
|
||||
{
|
||||
CheckForNull(key, Keys.POSTCONVERTER_KEY);
|
||||
registryConfig.Postconverter = key.GetValue(KeyNames.EXECUTABLE_FILE).ToString();
|
||||
}
|
||||
|
||||
using(var key = driver.OpenSubKey(Keys.PRECONVERTER_KEY))
|
||||
{
|
||||
CheckForNull(key, Keys.PRECONVERTER_KEY);
|
||||
registryConfig.Preconverter = key.GetValue(KeyNames.EXECUTABLE_FILE).ToString();
|
||||
}
|
||||
|
||||
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;
|
||||
registryConfig.IntermediateFormat = key.GetValue(KeyNames.FORMAT)?.ToString().ToLower() == "ps" ? IntermediateFormat.Ps : IntermediateFormat.Xps;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return registryConfig;
|
||||
}
|
||||
|
||||
[ContractAnnotation("key:null => void")]
|
||||
private void CheckForNull(RegistryKey key, string keyName)
|
||||
{
|
||||
if (key == null)
|
||||
{
|
||||
throw new NullReferenceException(keyName);
|
||||
}
|
||||
}
|
||||
|
||||
public IUserConfig GetUserRegistryConfig(string sid)
|
||||
{
|
||||
var regView = GetRegistryView();
|
||||
var userConfig = new UserRegistryConfig();
|
||||
|
||||
using (var users = RegistryKey.OpenBaseKey(RegistryHive.Users, regView))
|
||||
{
|
||||
var subKey = $@"{sid}\{Keys.PRINTER_DRIVER_KEY32}";
|
||||
using (var driver = users.OpenSubKey(subKey))
|
||||
{
|
||||
CheckForNull(driver, subKey);
|
||||
|
||||
using (var converter = driver.OpenSubKey(Keys.CONVERTER_KEY))
|
||||
{
|
||||
CheckForNull(converter, Keys.CONVERTER_KEY);
|
||||
|
||||
subKey = "Redirect";
|
||||
using (var redirect = converter.OpenSubKey(subKey))
|
||||
{
|
||||
CheckForNull(redirect, subKey);
|
||||
|
||||
userConfig.RedirectEnabled = (int?) redirect.GetValue("Enabled") == 1;
|
||||
userConfig.RedirectPrinter = redirect.GetValue("Printer").ToString();
|
||||
userConfig.Format = converter.GetValue("Format").ToString();
|
||||
|
||||
var dpiStr = (string)driver.GetValue("RENDER: DPI");
|
||||
if (dpiStr == null)
|
||||
{
|
||||
userConfig.UserRenderDpi = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
userConfig.UserRenderDpi = double.TryParse(dpiStr, out var dpiVal) ? dpiVal : (double?) null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return userConfig;
|
||||
}
|
||||
|
||||
private RegistryView GetRegistryView()
|
||||
{
|
||||
if (Environment.Is64BitOperatingSystem)
|
||||
{
|
||||
return RegistryView.Registry64;
|
||||
}
|
||||
|
||||
return RegistryView.Registry32;
|
||||
}
|
||||
|
||||
[NotNull]
|
||||
private string GetSubKey()
|
||||
{
|
||||
if (Environment.Is64BitOperatingSystem)
|
||||
{
|
||||
return Keys.PRINTER_DRIVER_KEY64;
|
||||
}
|
||||
|
||||
return Keys.PRINTER_DRIVER_KEY32;
|
||||
}
|
||||
}
|
||||
}
|
||||
95
Common/VirtualPrinter.Utils/Shell.cs
Normal file
95
Common/VirtualPrinter.Utils/Shell.cs
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
using VirtualPrinter.Agent.Core;
|
||||
using VirtualPrinter.Logging;
|
||||
|
||||
namespace VirtualPrinter.Utils
|
||||
{
|
||||
public class Shell : IShell
|
||||
{
|
||||
private readonly IVirtualPrinterLogger<Shell> _logger = new VirtualPrinterLogger<Shell>();
|
||||
|
||||
public void WriteIniEntry(string section, string key, string value, string iniFilePath)
|
||||
{
|
||||
Win32Sys.WritePrivateProfileString(section, key, value, iniFilePath);
|
||||
}
|
||||
|
||||
public T ReadIniEntry<T>(string section, string key, string iniFilePath)
|
||||
{
|
||||
var buffer = new StringBuilder(64 * 1024);
|
||||
Win32Sys.GetPrivateProfileString(section, key, string.Empty, buffer, buffer.Capacity, iniFilePath);
|
||||
var value = buffer.ToString().Trim();
|
||||
return (T)Convert.ChangeType(value, typeof(T));
|
||||
}
|
||||
|
||||
public void Execute(IJobInfo job, ISessionInfo session, string exe, string args)
|
||||
{
|
||||
var thr = new Thread
|
||||
(
|
||||
() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!File.Exists(exe))
|
||||
throw new FileNotFoundException(exe);
|
||||
#if DEBUG
|
||||
System.Diagnostics.Process.Start(exe, args);
|
||||
#else
|
||||
StartProcessAsUser(job, session, exe, args);
|
||||
#endif
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
LogError(exception, "Failed to create process");
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
thr.Start();
|
||||
}
|
||||
|
||||
public bool FileExists(string path)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
throw new ArgumentException("The path may not be null or empty.");
|
||||
}
|
||||
|
||||
return File.Exists(path);
|
||||
}
|
||||
|
||||
private void StartProcessAsUser([NotNull]IJobInfo job, [NotNull]ISessionInfo session, string exe, string args)
|
||||
{
|
||||
if (job == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(job));
|
||||
}
|
||||
|
||||
if (session == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(session));
|
||||
}
|
||||
|
||||
var cmd = $@"""{exe}"" {args}";
|
||||
var id = session.Id;
|
||||
var user = job.MachineName.TrimStart('\\') + '\\' + job.UserName;
|
||||
LogDebug($"Executing '{cmd}' for '{user}' ({id})...");
|
||||
Win32Sys.CreateProcessAsUser(id, user, cmd);
|
||||
}
|
||||
|
||||
private void LogDebug(string message, params object[] args)
|
||||
{
|
||||
_logger.Debug(message, args);
|
||||
}
|
||||
|
||||
private void LogError(Exception exception, string message, params object[] args)
|
||||
{
|
||||
_logger.Error(exception, message, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
69
Common/VirtualPrinter.Utils/VirtualPrinter.Utils.csproj
Normal file
69
Common/VirtualPrinter.Utils/VirtualPrinter.Utils.csproj
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
<?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>{CD1C8E9D-5335-41AC-B0C0-88FD7C7C55F3}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>VirtualPrinter.Utils</RootNamespace>
|
||||
<AssemblyName>VirtualPrinter.Utils</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<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' ">
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\..\Files\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="mscorlib" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Consts.cs" />
|
||||
<Compile Include="DirectoryHelper.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="RegistryRepository.cs" />
|
||||
<Compile Include="Shell.cs" />
|
||||
<Compile Include="Win32Sys.cs" />
|
||||
<Compile Include="Windows.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<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>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Cassia" Version="3.0.0-alpha.9" />
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2020.1.0" />
|
||||
<PackageReference Include="System.Security.Principal.Windows" Version="4.7.0" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
239
Common/VirtualPrinter.Utils/Win32Sys.cs
Normal file
239
Common/VirtualPrinter.Utils/Win32Sys.cs
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
namespace VirtualPrinter.Utils
|
||||
{
|
||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||
[SuppressMessage("ReSharper", "FieldCanBeMadeReadOnly.Global")]
|
||||
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
|
||||
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
|
||||
internal static class Win32Sys
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates process with given command line via Win32 API.
|
||||
/// Use this method to start a process as a service.
|
||||
/// </summary>
|
||||
/// <param name="sessId"></param>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="commandLine"></param>
|
||||
internal static void CreateProcessAsUser(int sessId, string user, string commandLine)
|
||||
{
|
||||
WTSQueryUserToken((uint) sessId, out var userToken);
|
||||
if (userToken.IsInvalid)
|
||||
{
|
||||
throw new InvalidOperationException($"Could not query user token for session {sessId}! (" + GetLastError() + ")",
|
||||
Windows.LastError);
|
||||
}
|
||||
|
||||
CreateProcessAsUser(userToken, user, commandLine);
|
||||
}
|
||||
|
||||
private static void CreateProcessAsUser([NotNull]SafeTokenHandle token, string user, string commandLine)
|
||||
{
|
||||
var processInformation = new PROCESS_INFORMATION();
|
||||
try
|
||||
{
|
||||
var securityAttributes = new SECURITY_ATTRIBUTES();
|
||||
securityAttributes.Length = Marshal.SizeOf(securityAttributes);
|
||||
|
||||
var startupInfo = new STARTUPINFO();
|
||||
startupInfo.cb = Marshal.SizeOf(startupInfo);
|
||||
startupInfo.lpDesktop = "winsta0\\default";
|
||||
|
||||
var info = new ProfileInfo();
|
||||
info.dwSize = Marshal.SizeOf(info);
|
||||
info.lpUserName = user;
|
||||
info.dwFlags = 1;
|
||||
|
||||
var result = LoadUserProfile(token, ref info);
|
||||
if (!result)
|
||||
{
|
||||
throw Windows.LastError;
|
||||
}
|
||||
|
||||
result = CreateEnvironmentBlock(out var lpEnvironment, token, false);
|
||||
if (!result)
|
||||
{
|
||||
throw Windows.LastError;
|
||||
}
|
||||
|
||||
result = CreateProcessAsUser
|
||||
(
|
||||
token,
|
||||
null,
|
||||
commandLine,
|
||||
ref securityAttributes,
|
||||
ref securityAttributes,
|
||||
false,
|
||||
0x00000400,
|
||||
lpEnvironment,
|
||||
null,
|
||||
ref startupInfo,
|
||||
ref processInformation
|
||||
);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
throw Windows.LastError;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (processInformation.hProcess != IntPtr.Zero)
|
||||
{
|
||||
CloseMyHandle(processInformation.hProcess);
|
||||
}
|
||||
|
||||
if (processInformation.hThread != IntPtr.Zero)
|
||||
{
|
||||
CloseMyHandle(processInformation.hThread);
|
||||
}
|
||||
|
||||
if (!token.IsInvalid)
|
||||
{
|
||||
token.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Classes
|
||||
|
||||
public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
|
||||
{
|
||||
private SafeTokenHandle() : base(true)
|
||||
{
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool CloseHandle(IntPtr handle);
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
return CloseHandle(handle);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{handle}";
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Structures
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PROCESS_INFORMATION
|
||||
{
|
||||
public IntPtr hProcess;
|
||||
public IntPtr hThread;
|
||||
public int dwProcessID;
|
||||
public int dwThreadID;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct STARTUPINFO
|
||||
{
|
||||
public int cb;
|
||||
public string lpReserved;
|
||||
public string lpDesktop;
|
||||
public string lpTitle;
|
||||
public int dwX;
|
||||
public int dwY;
|
||||
public int dwXSize;
|
||||
public int dwXCountChars;
|
||||
public int dwYCountChars;
|
||||
public int dwFillAttribute;
|
||||
public int dwFlags;
|
||||
public short wShowWindow;
|
||||
public short cbReserved2;
|
||||
public IntPtr lpReserved2;
|
||||
public IntPtr hStdInput;
|
||||
public IntPtr hStdOutput;
|
||||
public IntPtr hStdError;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct ProfileInfo
|
||||
{
|
||||
public int dwSize;
|
||||
public int dwFlags;
|
||||
public string lpUserName;
|
||||
public string lpProfilePath;
|
||||
public string lpDefaultPath;
|
||||
public string lpServerName;
|
||||
public string lpPolicyPath;
|
||||
public IntPtr hProfile;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SECURITY_ATTRIBUTES
|
||||
{
|
||||
public int Length;
|
||||
public IntPtr lpSecurityDescriptor;
|
||||
public bool bInheritHandle;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Windows interop
|
||||
|
||||
[DllImport("userenv.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
private static extern bool LoadUserProfile(SafeTokenHandle hToken, ref ProfileInfo lpProfileInfo);
|
||||
|
||||
[DllImport("userenv.dll", SetLastError = true)]
|
||||
private static extern bool CreateEnvironmentBlock(out IntPtr lpEnvironment,
|
||||
SafeTokenHandle hToken, bool bInherit);
|
||||
|
||||
[DllImport("kernel32.dll", EntryPoint = "CloseHandle", SetLastError = true,
|
||||
CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
|
||||
private static extern bool CloseMyHandle(IntPtr handle);
|
||||
|
||||
[DllImport("advapi32.dll", EntryPoint = "CreateProcessAsUser", SetLastError = true,
|
||||
CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
|
||||
private static extern bool CreateProcessAsUser(SafeTokenHandle hToken,
|
||||
string lpApplicationName, string lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes,
|
||||
ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandle,
|
||||
int dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory,
|
||||
ref STARTUPINFO lpStartupInfo, ref PROCESS_INFORMATION lpProcessInformation);
|
||||
|
||||
[DllImport("wtsapi32.dll", SetLastError = true)]
|
||||
private static extern bool WTSQueryUserToken(uint sessionId, out SafeTokenHandle Token);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern uint GetLastError();
|
||||
|
||||
[DllImport("kernel32")]
|
||||
public static extern int GetPrivateProfileString
|
||||
(
|
||||
string section,
|
||||
string key,
|
||||
string def,
|
||||
StringBuilder retVal,
|
||||
int size,
|
||||
string filePath
|
||||
);
|
||||
|
||||
[DllImport("kernel32")]
|
||||
public static extern long WritePrivateProfileString
|
||||
(
|
||||
string section,
|
||||
string key,
|
||||
string val,
|
||||
string filePath
|
||||
);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
14
Common/VirtualPrinter.Utils/Windows.cs
Normal file
14
Common/VirtualPrinter.Utils/Windows.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace VirtualPrinter.Utils
|
||||
{
|
||||
public class Windows
|
||||
{
|
||||
[NotNull]
|
||||
public static Exception LastError => new Win32Exception(Marshal.GetLastWin32Error());
|
||||
}
|
||||
}
|
||||
15
Installer/VirtualPrinter.SetupDriver/Defaults.cs
Normal file
15
Installer/VirtualPrinter.SetupDriver/Defaults.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
namespace VirtualPrinter.SetupDriver
|
||||
{
|
||||
public static class Defaults
|
||||
{
|
||||
/// <summary>
|
||||
/// The name that appears in the Windows "Printer & Scanner" menu.
|
||||
/// </summary>
|
||||
public const string PrinterName = "AMAGNO";
|
||||
|
||||
/// <summary>
|
||||
/// The printer port.
|
||||
/// </summary>
|
||||
public const string PrinterPort = "IP_VIRT_PRINTER";
|
||||
}
|
||||
}
|
||||
125
Installer/VirtualPrinter.SetupDriver/Program.cs
Normal file
125
Installer/VirtualPrinter.SetupDriver/Program.cs
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
using VirtualPrinter.Logging;
|
||||
using VirtualPrinter.Utils;
|
||||
|
||||
using static VirtualPrinter.SetupDriver.Windows;
|
||||
using static VirtualPrinter.SetupDriver.Defaults;
|
||||
|
||||
namespace VirtualPrinter.SetupDriver
|
||||
{
|
||||
internal class Program
|
||||
{
|
||||
private const string InstallCmd = "install";
|
||||
private const string TestCmd = "test";
|
||||
private const string ConfigCmd = "config";
|
||||
private const string UninstallCmd = "uninstall";
|
||||
|
||||
private static readonly IVirtualPrinterLogger<Program> Logger = new VirtualPrinterLogger<Program>();
|
||||
|
||||
private static void Main([CanBeNull]string[] args)
|
||||
{
|
||||
if (args == null || args.Length < 1)
|
||||
{
|
||||
NotUseful();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (args[0])
|
||||
{
|
||||
case InstallCmd:
|
||||
{
|
||||
if (args.Length < 2)
|
||||
{
|
||||
NotUseful();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (args[1].ToLower())
|
||||
{
|
||||
case "xps":
|
||||
try
|
||||
{
|
||||
AddPrinterPort(PrinterPort, "127.0.0.1", 9101);
|
||||
var isWin7 = Environment.OSVersion.VersionString.Contains("NT 6.1.");
|
||||
AddPrinter(PrinterName, "Microsoft XPS Document Writer" + (isWin7 ? string.Empty : " v4"), PrinterPort);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
LogError(exception, "Failed to add xps printer.");
|
||||
}
|
||||
break;
|
||||
case "ps":
|
||||
try
|
||||
{
|
||||
AddPrinterPort(PrinterPort, "127.0.0.1", 9101);
|
||||
new RegistryRepository().TryGetGhostscriptPath(out var ghostScriptPath);
|
||||
if (ghostScriptPath == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(ghostScriptPath), "Ghostscript path could not be found.");
|
||||
}
|
||||
|
||||
AddPrinter(PrinterName, "Ghostscript PDF", PrinterPort, Path.Combine(ghostScriptPath, @"lib\ghostpdf.inf"));
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
LogError(exception, "Failed to add ps printer.");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
NotUseful();
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case TestCmd: {
|
||||
TestPrinter(PrinterName);
|
||||
break;
|
||||
}
|
||||
case ConfigCmd: {
|
||||
try
|
||||
{
|
||||
ConfigPrinter(PrinterName);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
LogError(exception, "Failed to configurate printer {printerName}.", PrinterName);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case UninstallCmd: {
|
||||
try
|
||||
{
|
||||
DelPrinter(PrinterName);
|
||||
DelPrinterPort(PrinterPort);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
LogError(exception, "Failed to uninstall {printerName} on port {printerPort}.", PrinterName, PrinterPort);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
NotUseful();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void NotUseful()
|
||||
{
|
||||
var exception = new ArgumentNullException($"Use '{InstallCmd} [PS|XPS]', '{TestCmd}' or '{UninstallCmd}'!");
|
||||
LogError(exception, "Failed to handle the arguments.");
|
||||
throw exception;
|
||||
}
|
||||
|
||||
private static void LogError(Exception exception, string message, params object[] args)
|
||||
{
|
||||
Logger.Error(exception, message, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: AssemblyTitle("VirtualPrinter.SetupDriver")]
|
||||
[assembly: AssemblyDescription("The setup for the virtual printer driver")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
[assembly: Guid("12402f90-a2ae-4549-9142-f90650e2082a")]
|
||||
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
|
||||
[assembly: InternalsVisibleTo("properties")]
|
||||
84
Installer/VirtualPrinter.SetupDriver/Shell.cs
Normal file
84
Installer/VirtualPrinter.SetupDriver/Shell.cs
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
using VirtualPrinter.Logging;
|
||||
|
||||
namespace VirtualPrinter.SetupDriver
|
||||
{
|
||||
internal class Shell
|
||||
{
|
||||
private static readonly string WinFolder;
|
||||
|
||||
private static readonly IVirtualPrinterLogger<Shell> Logger = new VirtualPrinterLogger<Shell>();
|
||||
|
||||
static Shell()
|
||||
{
|
||||
WinFolder = Environment.GetEnvironmentVariable("windir") ?? @"C:\Windows";
|
||||
}
|
||||
|
||||
[NotNull]
|
||||
internal static string GetPrintInf()
|
||||
{
|
||||
try
|
||||
{
|
||||
var winFolder = Environment.GetEnvironmentVariable("windir") ?? @"C:\Windows";
|
||||
return Path.Combine(winFolder, "inf", "ntprint.inf");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
LogError(exception, "Cannot get PrintInf");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[NotNull]
|
||||
internal static string GetPrintVbs()
|
||||
{
|
||||
try
|
||||
{
|
||||
var printScripts = Path.Combine(WinFolder, "System32", "Printing_Admin_Scripts");
|
||||
return Directory.GetFiles(printScripts, "*port.vbs", SearchOption.AllDirectories).First();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
LogError(exception, "Cannot get PrintVbs");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Execute([NotNull]string exe, [NotNull]string args)
|
||||
{
|
||||
if (exe == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(exe));
|
||||
}
|
||||
|
||||
if (args == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(args));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Console.WriteLine(exe + " " + args);
|
||||
using(var proc = Process.Start(exe, args))
|
||||
{
|
||||
proc?.WaitForExit();
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
LogError(exception, "Cannot execute {exe} with the following args: {args}", exe, args);
|
||||
}
|
||||
}
|
||||
|
||||
private static void LogError(Exception exception, string message, params object[] args)
|
||||
{
|
||||
Logger.Error(exception, message, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
<?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>{12402F90-A2AE-4549-9142-F90650E2082A}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>VirtualPrinter.SetupDriver</RootNamespace>
|
||||
<AssemblyName>setupdrv</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.SetupDriver.Program</StartupObject>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Defaults.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Shell.cs" />
|
||||
<Compile Include="Windows.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>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2020.1.0" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
93
Installer/VirtualPrinter.SetupDriver/Windows.cs
Normal file
93
Installer/VirtualPrinter.SetupDriver/Windows.cs
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
using System;
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace VirtualPrinter.SetupDriver
|
||||
{
|
||||
internal static class Windows
|
||||
{
|
||||
public static void AddPrinter([NotNull]string name, [NotNull]string model, [NotNull]string port, [CanBeNull]string driver = null)
|
||||
{
|
||||
if (name == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
}
|
||||
|
||||
if (model == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(model));
|
||||
}
|
||||
|
||||
if (port == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(port));
|
||||
}
|
||||
|
||||
driver = driver ?? Shell.GetPrintInf();
|
||||
var args = $@"printui.dll,PrintUIEntry /if /b ""{name}"" /f ""{driver}"" /r ""{port}"" /m ""{model}"" /u";
|
||||
Shell.Execute("rundll32", args);
|
||||
}
|
||||
|
||||
public static void TestPrinter([NotNull]string name)
|
||||
{
|
||||
if (name == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
}
|
||||
|
||||
var args = $@"printui.dll,PrintUIEntry /k /n ""{name}""";
|
||||
Shell.Execute("rundll32", args);
|
||||
}
|
||||
|
||||
public static void ConfigPrinter([NotNull]string name)
|
||||
{
|
||||
if (name == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
}
|
||||
|
||||
var args = $@"printui.dll,PrintUIEntry /e /n ""{name}""";
|
||||
Shell.Execute("rundll32", args);
|
||||
}
|
||||
|
||||
public static void DelPrinter([NotNull]string name)
|
||||
{
|
||||
if (name == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
}
|
||||
|
||||
var args = $@"printui.dll,PrintUIEntry /dl /n ""{name}""";
|
||||
Shell.Execute("rundll32", args);
|
||||
}
|
||||
|
||||
public static void AddPrinterPort([NotNull]string name, [NotNull]string ip, int port, [CanBeNull]string vbs = null)
|
||||
{
|
||||
if (name == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
}
|
||||
|
||||
if (ip == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(ip));
|
||||
}
|
||||
|
||||
vbs = vbs ?? Shell.GetPrintVbs();
|
||||
var args = $@"""{vbs}"" -a -r {name} -h {ip} -o raw -n {port}";
|
||||
Shell.Execute("cscript", args);
|
||||
}
|
||||
|
||||
public static void DelPrinterPort([NotNull]string name, [CanBeNull]string vbs = null)
|
||||
{
|
||||
if (name == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
}
|
||||
|
||||
vbs = vbs ?? Shell.GetPrintVbs();
|
||||
var args = $@"""{vbs}"" -d -r {name}";
|
||||
Shell.Execute("cscript", args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
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.WixSharpInstaller")]
|
||||
[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("a668846e-54c7-483d-9cf7-48f77ea398ca")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
171
Installer/VirtualPrinter.WixSharpInstaller/Script.cs
Normal file
171
Installer/VirtualPrinter.WixSharpInstaller/Script.cs
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
// ReSharper disable once RedundantUsingDirective
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
using VirtualPrinter.Utils;
|
||||
|
||||
using WixSharp;
|
||||
|
||||
using Action = WixSharp.Action;
|
||||
using File = WixSharp.File;
|
||||
using Files = VirtualPrinter.Utils.Files;
|
||||
using RegistryHive = WixSharp.RegistryHive;
|
||||
|
||||
namespace VirtualPrinter.WixSharpInstaller
|
||||
{
|
||||
public class Script
|
||||
{
|
||||
private static string _filesDir;
|
||||
const string SetupDriverId = "setupdrv_exe";
|
||||
|
||||
public static void Main([NotNull]string[] args)
|
||||
{
|
||||
var workingDir = "";
|
||||
if (args.Length > 0)
|
||||
{
|
||||
foreach(var cmd in args)
|
||||
{
|
||||
if (cmd.Contains(@"/p:"))
|
||||
{
|
||||
workingDir = cmd.Remove(0, 3);
|
||||
Console.WriteLine(workingDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (workingDir.IsNullOrEmpty())
|
||||
{
|
||||
throw new ArgumentException("Argument for working directory (/p) not set.");
|
||||
}
|
||||
|
||||
_filesDir = Path.Combine(workingDir, Files.FILES);
|
||||
var feature = new Feature("VPD");
|
||||
var printerServiceFile = new File(feature, Path.Combine(_filesDir, Files.PRINTER_SERVICE_EXE))
|
||||
{
|
||||
ServiceInstaller = new ServiceInstaller
|
||||
{
|
||||
Name = "VirtualPrinterService",
|
||||
StartOn = SvcEvent.Install_Wait,
|
||||
StopOn = SvcEvent.InstallUninstall_Wait,
|
||||
RemoveOn = SvcEvent.Uninstall_Wait,
|
||||
ErrorControl = SvcErrorControl.normal,
|
||||
ConfigureServiceTrigger = ConfigureServiceTrigger.None
|
||||
}
|
||||
};
|
||||
|
||||
var project = new ManagedProject("VPDInstaller")
|
||||
{
|
||||
Name = "Virtual Printer Driver",
|
||||
GUID = new Guid("8712D2CD-A9F6-456F-99C8-92C2BB070596"),
|
||||
UpgradeCode = new Guid("0B37A935-EDEC-4ACA-9307-6D8299496C1D"),
|
||||
UI = WUI.WixUI_InstallDir,
|
||||
Version = Version.Parse(FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).FileVersion),
|
||||
LicenceFile = Files.LICENCE_FILE,
|
||||
Dirs = CreateProjectDirs(feature, printerServiceFile),
|
||||
Actions = CreateActions(),
|
||||
RegValues = CreateRegValues(feature).ToArray(),
|
||||
InstallPrivileges = InstallPrivileges.elevated
|
||||
};
|
||||
|
||||
project.BuildMsi();
|
||||
}
|
||||
|
||||
[NotNull, ItemNotNull]
|
||||
private static Dir[] CreateProjectDirs
|
||||
(
|
||||
Feature feature,
|
||||
File printerServiceFile
|
||||
)
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
new Dir
|
||||
(
|
||||
@"%ProgramFiles%\MyPrinterDriver\",
|
||||
new DirFiles(feature, _filesDir + @"\*", s => !s.EndsWith(".exe")),
|
||||
new File(new Id(SetupDriverId), feature, Path.Combine(_filesDir, Files.SETUP_DRIVER_EXE)),
|
||||
new File(feature, Path.Combine(_filesDir, Files.DILIVERY_EXE)),
|
||||
new File(feature, Path.Combine(_filesDir, Files.AGENT_PROGRESS_EXE)),
|
||||
printerServiceFile
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
[NotNull, ItemNotNull]
|
||||
private static Action[] CreateActions()
|
||||
{
|
||||
return new Action[]
|
||||
{
|
||||
new InstalledFileAction(SetupDriverId, "install ps", Return.check, When.After, Step.InstallFinalize, Condition.NOT_Installed),
|
||||
new InstalledFileAction(SetupDriverId, "uninstall", Return.check, When.Before, Step.RemoveFiles, Condition.BeingUninstalled)
|
||||
};
|
||||
}
|
||||
|
||||
[NotNull]
|
||||
private static IEnumerable<RegValue> CreateRegValues(Feature feature)
|
||||
{
|
||||
var converterKey = $@"{Keys.PRINTER_DRIVER_KEY32}\{Keys.CONVERTER_KEY}";
|
||||
|
||||
var regValues = new List<RegValue>();
|
||||
regValues.AddRange(CreateLocalMachineValues(feature, converterKey));
|
||||
regValues.AddRange(CreateCurrentUserValues(feature, converterKey));
|
||||
|
||||
return regValues;
|
||||
}
|
||||
|
||||
[NotNull]
|
||||
private static IEnumerable<RegValue> CreateLocalMachineValues(Feature feature, string converterKey)
|
||||
{
|
||||
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;
|
||||
|
||||
return new List<RegValue>
|
||||
{
|
||||
new RegValue(feature, registryHive, Keys.PRINTER_DRIVER_KEY32, KeyNames.INSTALLATION_DIR, "[INSTALLDIR]"),
|
||||
new RegValue(feature, registryHive, postConverterKey, KeyNames.EXECUTABLE_FILE, Files.POST_CONVERTER),
|
||||
new RegValue(feature, registryHive, preConverterKey, KeyNames.EXECUTABLE_FILE, Files.PRE_CONVERTER),
|
||||
new RegValue(feature, registryHive, converterKey, KeyNames.SERVER_PORT, 9101) {AttributesDefinition = "Type=integer"},
|
||||
new RegValue(feature, registryHive, converterKey, KeyNames.THREADS, 2),
|
||||
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"},
|
||||
new RegValue(feature, registryHive, converterPdfKey, KeyNames.PRODUCE_PDFA, 1) {AttributesDefinition = "Type=integer"},
|
||||
new RegValue(feature, registryHive, converterPdfKey, KeyNames.ALLOW_COPYING, 1) {AttributesDefinition = "Type=integer"},
|
||||
new RegValue(feature, registryHive, converterPdfKey, KeyNames.ALLOW_PRINTING, 1) {AttributesDefinition = "Type=integer"},
|
||||
new RegValue(feature, registryHive, converterPdfKey, KeyNames.SUBSETTING, 1) {AttributesDefinition = "Type=integer"},
|
||||
new RegValue(feature, registryHive, converterPdfKey,KeyNames.QUALITY , 80),
|
||||
new RegValue(feature, registryHive, converterTiffKey, KeyNames.ENABLED, 1) {AttributesDefinition = "Type=integer"},
|
||||
new RegValue(feature, registryHive, converterTiffKey, KeyNames.BITS_PIXEL, 24),
|
||||
new RegValue(feature, registryHive, converterTiffKey, KeyNames.MULTIPAGE, 1) {AttributesDefinition = "Type=integer"},
|
||||
new RegValue(feature, registryHive, converterTiffKey, KeyNames.COMPRESSION, 8)
|
||||
};
|
||||
}
|
||||
|
||||
[NotNull]
|
||||
private static IEnumerable<RegValue> CreateCurrentUserValues(Feature feature, string converterKey)
|
||||
{
|
||||
var redirectKey = $@"{Keys.PRINTER_DRIVER_KEY32}\{Keys.CONVERTER_REDIRECT_KEY}";
|
||||
var registryHive = RegistryHive.CurrentUser;
|
||||
|
||||
return new List<RegValue>
|
||||
{
|
||||
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, redirectKey, KeyNames.ENABLED, 1) {AttributesDefinition = "Type=integer"},
|
||||
new RegValue(feature, registryHive, redirectKey, KeyNames.PRINTER, "")
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<?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>{A668846E-54C7-483D-9CF7-48F77EA398CA}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>VirtualPrinter.WixSharpInstaller</RootNamespace>
|
||||
<AssemblyName>VPDInstaller</AssemblyName>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile />
|
||||
</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.WixSharpInstaller.Script</StartupObject>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Script.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<None Include="wix\$(ProjectName).g.wxs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<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" />
|
||||
<PackageReference Include="WixSharp.bin" Version="1.14.8" />
|
||||
<PackageReference Include="WixSharp.wix.bin" Version="3.11.2" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- <Import Project="..\..\packages\WixSharp.bin\1.14.8\build\WixSharp.bin.targets" Condition="Exists('..\..\packages\WixSharp.bin\1.14.8\build\WixSharp.bin.targets')" />-->
|
||||
<!-- <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">-->
|
||||
<!-- <PropertyGroup>-->
|
||||
<!-- <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>-->
|
||||
<!-- </PropertyGroup>-->
|
||||
<!-- <Error Condition="!Exists('..\..\packages\WixSharp.bin\1.14.8\build\WixSharp.bin.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\WixSharp.bin\1.14.8\build\WixSharp.bin.targets'))" />-->
|
||||
<!-- <Error Condition="!Exists('..\..\packages\WixSharp\1.14.8\build\WixSharp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\WixSharp\1.14.8\build\WixSharp.targets'))" />-->
|
||||
<!-- </Target>-->
|
||||
</Project>
|
||||
3
Installer/VirtualPrinter.WixSharpInstaller/app.config
Normal file
3
Installer/VirtualPrinter.WixSharpInstaller/app.config
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/></startup></configuration>
|
||||
7
NuGet.Config
Normal file
7
NuGet.Config
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<config>
|
||||
<add key="repositoryPath" value=".\packages" />
|
||||
<add key="globalPackagesFolder" value=".\packages" />
|
||||
</config>
|
||||
</configuration>
|
||||
23
UI/VirtualPrinter.ProgressInfo.Autofac/ProgressInfoModule.cs
Normal file
23
UI/VirtualPrinter.ProgressInfo.Autofac/ProgressInfoModule.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
using Autofac;
|
||||
|
||||
using VirtualPrinter.ProgressInfo.Core;
|
||||
using VirtualPrinter.ProgressInfo.Core.Message;
|
||||
using VirtualPrinter.ProgressInfo.Lib;
|
||||
using VirtualPrinter.ProgressInfo.Lib.Interfaces;
|
||||
using VirtualPrinter.ProgressInfo.Lib.Message;
|
||||
|
||||
namespace VirtualPrinter.ProgressInfo.Autofac
|
||||
{
|
||||
public class ProgressInfoModule : Module
|
||||
{
|
||||
protected override void Load(ContainerBuilder builder)
|
||||
{
|
||||
builder.RegisterType<ProgressInfoBroker>().As<IProgressInfo>().SingleInstance();
|
||||
builder.RegisterType<MessageFactory>().As<IMessageFactory>();
|
||||
builder.RegisterType<Message>();
|
||||
builder.RegisterType<ProgressInfoServerFactory>().As<IProgressInfoServerFactory>();
|
||||
builder.RegisterType<ProgressInfoProcessManager>().As<IProgressInfoProcessManager>();
|
||||
builder.RegisterType<ProgressInfoServer>().As<IProgressInfoServer>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Allgemeine Informationen über eine Assembly werden über die folgenden
|
||||
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
|
||||
// die einer Assembly zugeordnet sind.
|
||||
[assembly: AssemblyTitle("VirtualPrinter.ProgressInfo.Autofac")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
|
||||
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
|
||||
// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
|
||||
[assembly: Guid("17e2cf8a-462c-4130-9faf-f1ca5fc4e06d")]
|
||||
|
||||
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
|
||||
//
|
||||
// Hauptversion
|
||||
// Nebenversion
|
||||
// Buildnummer
|
||||
// Revision
|
||||
//
|
||||
// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
|
||||
// indem Sie "*" wie unten gezeigt eingeben:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
<?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>{17E2CF8A-462C-4130-9FAF-F1CA5FC4E06D}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>VirtualPrinter.ProgressInfo.Autofac</RootNamespace>
|
||||
<AssemblyName>VirtualPrinter.ProgressInfo.Autofac</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<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' ">
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\..\Files\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="mscorlib" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Numerics" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ProgressInfoModule.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\VirtualPrinter.ProgressInfo.Core\VirtualPrinter.ProgressInfo.Core.csproj">
|
||||
<Project>{24D28558-C825-43E6-85D2-7C59F4A97698}</Project>
|
||||
<Name>VirtualPrinter.ProgressInfo.Core</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\VirtualPrinter.ProgressInfo.Lib\VirtualPrinter.ProgressInfo.Lib.csproj">
|
||||
<Project>{d66f55e5-b3f7-4c61-a4f2-b55c4d412e01}</Project>
|
||||
<Name>VirtualPrinter.ProgressInfo.Lib</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autofac" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="5.0.0-rc.2.20475.5" />
|
||||
<PackageReference Include="System.Buffers" Version="4.5.1" />
|
||||
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="4.7.1" />
|
||||
<PackageReference Include="System.Memory" Version="4.5.4" />
|
||||
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
|
||||
<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>
|
||||
11
UI/VirtualPrinter.ProgressInfo.Core/IProgressInfo.cs
Normal file
11
UI/VirtualPrinter.ProgressInfo.Core/IProgressInfo.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
using VirtualPrinter.Agent.Core;
|
||||
|
||||
namespace VirtualPrinter.ProgressInfo.Core
|
||||
{
|
||||
public interface IProgressInfo
|
||||
{
|
||||
void Progress(IJob job, uint val);
|
||||
void Initialize(IJob job);
|
||||
void Finish(IJob job);
|
||||
}
|
||||
}
|
||||
6
UI/VirtualPrinter.ProgressInfo.Core/Message/IFinal.cs
Normal file
6
UI/VirtualPrinter.ProgressInfo.Core/Message/IFinal.cs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
namespace VirtualPrinter.ProgressInfo.Core.Message
|
||||
{
|
||||
public interface IFinal : IMessage
|
||||
{
|
||||
}
|
||||
}
|
||||
6
UI/VirtualPrinter.ProgressInfo.Core/Message/IMessage.cs
Normal file
6
UI/VirtualPrinter.ProgressInfo.Core/Message/IMessage.cs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
namespace VirtualPrinter.ProgressInfo.Core.Message
|
||||
{
|
||||
public interface IMessage
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
using JetBrains.Annotations;
|
||||
|
||||
namespace VirtualPrinter.ProgressInfo.Core.Message
|
||||
{
|
||||
public interface IMessageFactory
|
||||
{
|
||||
[NotNull]
|
||||
Message CreateStart();
|
||||
|
||||
[NotNull]
|
||||
Message CreateStep(uint val);
|
||||
|
||||
[NotNull]
|
||||
Message CreateFinal();
|
||||
}
|
||||
}
|
||||
6
UI/VirtualPrinter.ProgressInfo.Core/Message/IStart.cs
Normal file
6
UI/VirtualPrinter.ProgressInfo.Core/Message/IStart.cs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
namespace VirtualPrinter.ProgressInfo.Core.Message
|
||||
{
|
||||
public interface IStart : IMessage
|
||||
{
|
||||
}
|
||||
}
|
||||
7
UI/VirtualPrinter.ProgressInfo.Core/Message/IStep.cs
Normal file
7
UI/VirtualPrinter.ProgressInfo.Core/Message/IStep.cs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
namespace VirtualPrinter.ProgressInfo.Core.Message
|
||||
{
|
||||
public interface IStep : IMessage
|
||||
{
|
||||
uint Value { get; set; }
|
||||
}
|
||||
}
|
||||
17
UI/VirtualPrinter.ProgressInfo.Core/Message/Message.cs
Normal file
17
UI/VirtualPrinter.ProgressInfo.Core/Message/Message.cs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
|
||||
namespace VirtualPrinter.ProgressInfo.Core.Message
|
||||
{
|
||||
[Serializable]
|
||||
public class Message
|
||||
{
|
||||
public Message(MessageType type, uint val)
|
||||
{
|
||||
Type = type;
|
||||
Value = val;
|
||||
}
|
||||
|
||||
public MessageType Type { get; }
|
||||
public uint Value { get; }
|
||||
}
|
||||
}
|
||||
11
UI/VirtualPrinter.ProgressInfo.Core/Message/MessageType.cs
Normal file
11
UI/VirtualPrinter.ProgressInfo.Core/Message/MessageType.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
namespace VirtualPrinter.ProgressInfo.Core.Message
|
||||
{
|
||||
public enum MessageType : uint
|
||||
{
|
||||
None,
|
||||
Initialize,
|
||||
Finalize,
|
||||
Step,
|
||||
Close
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Allgemeine Informationen über eine Assembly werden über die folgenden
|
||||
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
|
||||
// die einer Assembly zugeordnet sind.
|
||||
[assembly: AssemblyTitle("VirtualPrinter.ProgressInfo.Core")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
|
||||
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
|
||||
// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
|
||||
[assembly: Guid("24d28558-c825-43e6-85d2-7c59f4a97698")]
|
||||
|
||||
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
|
||||
//
|
||||
// Hauptversion
|
||||
// Nebenversion
|
||||
// Buildnummer
|
||||
// Revision
|
||||
//
|
||||
// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
|
||||
// indem Sie "*" wie unten gezeigt eingeben:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue