We have some print server software written in C# (which P/Invokes functions from winspool.drv). Some of the “printers” are actually virtual printers that print to a directory. The code to install such a printer is:
public override void AddLocalDirectoryPrinter(string printerName, string directory)
{
IntPtr hPrinter = IntPtr.Zero;
try
{
PRINTER_DEFAULTS pd;
PRINTER_INFO_2 pi2;
pd.datatype = null;
pd.pDevMode = IntPtr.Zero;
// Access = PRINTER_ALL_ACCESS
// http://msdn.microsoft.com/en-us/library/cc244650%28v=prot.10%29.aspx
pd.desiredAccess = PRINTER_ALL_ACCESS;
// Attributes = PUBLISHED | DO_COMPLETE_FIRST | SHARED
// http://msdn.microsoft.com/en-us/library/aa394363%28v=vs.85%29.aspx
pi2.attributes = 0x2208;
pi2.averagePpm = 0;
pi2.jobs = 0;
pi2.defaultPriority = 0;
pi2.comment = "Auto-Generated by [name of program]";
pi2.datatype = "RAW";
pi2.pDevMode = IntPtr.Zero;
pi2.driverName = "Generic / Text Only";
pi2.location = string.Empty;
pi2.parameters = string.Empty;
pi2.portName = directory;
pi2.printerName = printerName.ToUpperInvariant();
pi2.printProcessor = "WinPrint";
pi2.priority = 0;
pi2.pSecurityDescriptor = IntPtr.Zero;
pi2.sepFile = string.Empty;
pi2.serverName = string.Empty;
pi2.shareName = printerName.ToUpperInvariant();
pi2.startTime = 0;
pi2.status = 0;
pi2.untilTime = 0;
hPrinter = AddPrinter(null, 2, ref pi2);
if (hPrinter == IntPtr.Zero)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
catch (Exception ex)
{
throw new PrintingException("Failed to add printer", ex);
}
finally
{
if (hPrinter != IntPtr.Zero)
{
ClosePrinter(hPrinter);
}
}
}
On 32-bit Windows XP, the above code runs without error. But on 64-bit Windows 7, the call to AddPrinter fails with Windows error 1796 (“The specified port is unknown”).
Why does it work on one version of Windows but not another?
It turns out that I just needed to build a 64-bit version of dirport.dll.