From 80c6ba8f583856011c98d02af6eb2807a1f2660e Mon Sep 17 00:00:00 2001 From: S T Chan Date: Thu, 12 Dec 2013 19:29:31 -0500 Subject: [PATCH] Added uninstall methods, and application manifest for PdfScribeUnitTests project --- PdfScribe/NativeMethods.cs | 48 +++++---- PdfScribe/PdfScribeInstaller.cs | 102 +++++++++++++++++-- PdfScribeUnitTests/PdfScribeUnitTests.csproj | 6 +- PdfScribeUnitTests/UnitTests.cs | 22 +++- PdfScribeUnitTests/app.manifest | 48 +++++++++ 5 files changed, 197 insertions(+), 29 deletions(-) create mode 100644 PdfScribeUnitTests/app.manifest diff --git a/PdfScribe/NativeMethods.cs b/PdfScribe/NativeMethods.cs index 1668f64..40c5154 100644 --- a/PdfScribe/NativeMethods.cs +++ b/PdfScribe/NativeMethods.cs @@ -98,23 +98,23 @@ namespace PdfScribe public uint AveragePPM; } - public static class NativeMethods + internal static class NativeMethods { + #region winspool + [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] - public static extern bool EnumMonitors(string pName, uint level, IntPtr pMonitors, uint cbBuf, ref uint pcbNeeded, ref uint pcReturned); + internal static extern bool EnumMonitors(string pName, uint level, IntPtr pMonitors, uint cbBuf, ref uint pcbNeeded, ref uint pcReturned); [DllImport("winspool.drv", SetLastError = true, CharSet = CharSet.Auto)] - public static extern Int32 AddMonitor(String pName, UInt32 Level, ref MONITOR_INFO_2 pMonitors); + internal static extern Int32 AddMonitor(String pName, UInt32 Level, ref MONITOR_INFO_2 pMonitors); [DllImport("winspool.drv", SetLastError = true, CharSet = CharSet.Auto)] - public static extern Int32 DeleteMonitor(String pName, String pEnvironment, String pMonitorName); + internal static extern Int32 DeleteMonitor(String pName, String pEnvironment, String pMonitorName); - [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] - public static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr); [DllImport("winspool.drv", EntryPoint = "XcvDataW", SetLastError = true)] - public static extern bool XcvData(IntPtr hXcv, + internal static extern bool XcvData(IntPtr hXcv, [MarshalAs(UnmanagedType.LPWStr)] string pszDataName, IntPtr pInputData, uint cbInputData, @@ -126,38 +126,50 @@ namespace PdfScribe [DllImport("winspool.drv", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)] - public static extern int AddPrinter(string pName, uint Level, [In] ref PRINTER_INFO_2 pPrinter); + internal static extern int AddPrinter(string pName, uint Level, [In] ref PRINTER_INFO_2 pPrinter); [DllImport("winspool.drv", EntryPoint = "OpenPrinterA", SetLastError = true)] - public static extern int OpenPrinter( - string pPrinterName, - ref IntPtr phPrinter, - PRINTER_DEFAULTS pDefault); + internal static extern int OpenPrinter(string pPrinterName, + ref IntPtr phPrinter, + PRINTER_DEFAULTS pDefault); [DllImport("winspool.drv", SetLastError = true)] - public static extern int ClosePrinter(IntPtr hPrinter); + internal static extern int ClosePrinter(IntPtr hPrinter); [DllImport("winspool.drv", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)] - public static extern bool DeletePrinter(IntPtr hPrinter); + internal static extern bool DeletePrinter(IntPtr hPrinter); [DllImport("winspool.drv", EntryPoint="AddPrinterDriver", CharSet = CharSet.Auto, SetLastError = true)] - public static extern bool AddPrinterDriver(String pName, + internal static extern bool AddPrinterDriver(String pName, int Level, ref DRIVER_INFO_6 pDriverInfo); [DllImport("winspool.drv")] - public static extern bool GetPrinterDriverDirectory(StringBuilder pName, + internal static extern bool GetPrinterDriverDirectory(StringBuilder pName, StringBuilder pEnv, int Level, [Out] StringBuilder outPath, int bufferSize, ref int Bytes); + [DllImport("winspool.drv", EntryPoint = "DeletePrinterDriverEx", CharSet = CharSet.Auto, SetLastError = true)] + internal static extern bool DeletePrinterDriverEx(String pName, + String pEnvironment, + String pDriverName, + uint dwDeleteFlag, + uint dwVersionFlag); + + #endregion + + #region Kernel32 [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] - public static extern bool Wow64RevertWow64FsRedirection(IntPtr ptr); + internal static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr); - + [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] + internal static extern bool Wow64RevertWow64FsRedirection(IntPtr ptr); + + #endregion } } diff --git a/PdfScribe/PdfScribeInstaller.cs b/PdfScribe/PdfScribeInstaller.cs index 9ba03a1..865ce19 100644 --- a/PdfScribe/PdfScribeInstaller.cs +++ b/PdfScribe/PdfScribeInstaller.cs @@ -10,6 +10,24 @@ namespace PdfScribe { public class PdfScribeInstaller { + #region Printer Driver Win32 API Constants + + const uint DRIVER_KERNELMODE = 0x00000001; + const uint DRIVER_USERMODE = 0x00000002; + + const uint APD_STRICT_UPGRADE = 0x00000001; + const uint APD_STRICT_DOWNGRADE = 0x00000002; + const uint APD_COPY_ALL_FILES = 0x00000004; + const uint APD_COPY_NEW_FILES = 0x00000008; + const uint APD_COPY_FROM_DIRECTORY = 0x00000010; + + const uint DPD_DELETE_UNUSED_FILES = 0x00000001; + const uint DPD_DELETE_SPECIFIC_VERSION = 0x00000002; + const uint DPD_DELETE_ALL_FILES = 0x00000004; + + #endregion + + const string ENVIRONMENT_64 = "Windows x64"; const string PRINTERNAME = "PDF Scribe"; @@ -23,17 +41,20 @@ namespace PdfScribe const string DRIVERMANUFACTURER = "S T Chan"; const string DRIVERFILE = "PSCRIPT5.DLL"; - const int DRIVERFILE_INDEX = 0; const string DRIVERUIFILE = "PS5UI.DLL"; - const int DRIVERUIFILE_INDEX = 1; const string DRIVERHELPFILE = "PSCRIPT.HLP"; - const int DRIVERHELPFILE_INDEX = 2; const string DRIVERDATAFILE = "SCPDFPRN.PPD"; - const int DRIVERDATAFILE_INDEX = 3; #region Port operations +#if DEBUG + public int AddPdfScribePort_Test(string portName) + { + return AddPdfScribePort(portName); + } +#endif + private int AddPdfScribePort(string portName) { return DoXcvDataPortOperation(portName, "AddPort"); @@ -110,7 +131,15 @@ namespace PdfScribe // the system directory String fileSourcePath = Path.Combine(monitorFilePath, MONITORDLL); String fileDestinationPath = Path.Combine(Environment.SystemDirectory, MONITORDLL); - File.Copy(fileSourcePath, fileDestinationPath, true); + try + { + File.Copy(fileSourcePath, fileDestinationPath, true); + } + catch (IOException) + { + // File in use, log - + // this is OK because it means the file is already there + } MONITOR_INFO_2 newMonitor = new MONITOR_INFO_2(); newMonitor.pName = PORTMONITOR; newMonitor.pEnvironment = ENVIRONMENT_64; @@ -242,7 +271,7 @@ namespace PdfScribe } else { - throw new ApplicationException("Call to winspool.drv succeeded with a zero size buffer - unexpected error."); + throw new ApplicationException("Call to EnumMonitors in winspool.drv succeeded with a zero size buffer - unexpected error."); } return portMonitors; @@ -269,7 +298,7 @@ namespace PdfScribe #if DEBUG public bool InstallSoftscanPrinter_Test() { - String driverSourceDirectory = @"C:\Code\OaisisRedmonInstaller\Lib\"; + String driverSourceDirectory = @"C:\Code\PdfScribe\Lib\"; String[] driverFilesToCopy = new String[] { DRIVERFILE, DRIVERDATAFILE, DRIVERHELPFILE, DRIVERUIFILE }; String[] dependentFilesToCopy = new String[] { "PSCRIPT.NTF" }; return InstallPdfScribePrinter(driverSourceDirectory, driverFilesToCopy, dependentFilesToCopy); @@ -291,11 +320,11 @@ namespace PdfScribe bool printerInstalled = false; String driverDirectory = RetrievePrinterDriverDirectory(); - if (AddPdfScribePort(PORTNAME) == 0) + if (AddPdfScribePortMonitor(driverSourceDirectory)) { if (CopyPrinterDriverFiles(driverSourceDirectory, driverFilesToCopy.Concat(dependentFilesToCopy).ToArray())) { - if (AddPdfScribePortMonitor(driverSourceDirectory)) + if (AddPdfScribePort(PORTNAME) == 0) { if (InstallPrinterDriver(driverDirectory, dependentFilesToCopy)) { @@ -307,6 +336,22 @@ namespace PdfScribe return printerInstalled; } + + /// + /// + /// + /// + public bool UninstallPdfScribePrinter() + { + bool printerUninstalled = false; + + DeletePdfScribePrinter(); + RemovePDFScribePrinterDriver(); + DeletePdfScribePort(PORTNAME); + RemovePdfScribePortMonitor(); + return printerUninstalled; + } + private bool CopyPrinterDriverFiles(String driverSourceDirectory, String[] filesToCopy) { @@ -412,6 +457,17 @@ namespace PdfScribe } + public bool RemovePDFScribePrinterDriver() + { + bool printerRemoved = NativeMethods.DeletePrinterDriverEx(null, ENVIRONMENT_64, DRIVERNAME, DPD_DELETE_UNUSED_FILES, 3); + if (!printerRemoved) + { + throw new Win32Exception(Marshal.GetLastWin32Error(), "Could not remove PDF Scribe printer driver"); + } + return printerRemoved; + } + + private bool AddPdfScribePrinter() { bool printerAdded = false; @@ -439,6 +495,34 @@ namespace PdfScribe return printerAdded; } + private bool DeletePdfScribePrinter() + { + bool printerDeleted = false; + + PRINTER_DEFAULTS scribeDefaults = new PRINTER_DEFAULTS(); + scribeDefaults.DesiredAccess = 0x000F000C; // All access + scribeDefaults.pDatatype = null; + scribeDefaults.pDevMode = IntPtr.Zero; + + IntPtr scribeHandle = IntPtr.Zero; + try + { + if (NativeMethods.OpenPrinter(PRINTERNAME, ref scribeHandle, scribeDefaults) != 0) + { + if (NativeMethods.DeletePrinter(scribeHandle)) + printerDeleted = true; + } + else + { + // log error + } + } + finally + { + if (scribeHandle != IntPtr.Zero) NativeMethods.ClosePrinter(scribeHandle); + } + return printerDeleted; + } #endregion diff --git a/PdfScribeUnitTests/PdfScribeUnitTests.csproj b/PdfScribeUnitTests/PdfScribeUnitTests.csproj index 40a73e8..0cb4a3c 100644 --- a/PdfScribeUnitTests/PdfScribeUnitTests.csproj +++ b/PdfScribeUnitTests/PdfScribeUnitTests.csproj @@ -13,6 +13,7 @@ v4.0 Client 512 + false publish\ true Disk @@ -25,7 +26,6 @@ true 0 1.0.0.%2a - false false true @@ -71,6 +71,9 @@ true true + + app.manifest + ..\Lib\nunit-console-runner.dll @@ -108,6 +111,7 @@ + diff --git a/PdfScribeUnitTests/UnitTests.cs b/PdfScribeUnitTests/UnitTests.cs index a76d6d2..1f26637 100644 --- a/PdfScribeUnitTests/UnitTests.cs +++ b/PdfScribeUnitTests/UnitTests.cs @@ -17,12 +17,32 @@ namespace PdfScribeUnitTests { } #endregion - [Test] + //[Test] public void Test_DeletePdfScribePort() { var scribeInstaller = new PdfScribeInstaller(); scribeInstaller.DeletePdfScribePort("SSCAN"); } + //[Test] + public void Test_RemovePdfScribeDriver() + { + var scribeInstaller = new PdfScribeInstaller(); + scribeInstaller.RemovePDFScribePrinterDriver(); + } + + //[Test] + public void Test_InstallPdfScribePrinter() + { + var scribeInstaller = new PdfScribeInstaller(); + scribeInstaller.InstallSoftscanPrinter_Test(); + } + + [Test] + public void Test_UninstallPdfScribePrinter() + { + var scribeInstaller = new PdfScribeInstaller(); + scribeInstaller.UninstallPdfScribePrinter(); + } } } diff --git a/PdfScribeUnitTests/app.manifest b/PdfScribeUnitTests/app.manifest new file mode 100644 index 0000000..9e0556d --- /dev/null +++ b/PdfScribeUnitTests/app.manifest @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +