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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+