Я использую код, который я нашел в Интернете, который был решением чужой подобной проблемы с печатью. Кажется, что код работает нормально и даже ошибки, когда я ожидаю его (например, когда я целенаправленно вхожу в плохое имя принтера). Проблема, с которой я сталкиваюсь, заключается в том, что вызов interop для метода WritePrinter от winspool.drv не приводит к тому, что принтер печатает что-либо, даже если этот метод возвращает «true». Любые идеи, почему принтер на самом деле не печатает ???C# winspool.drv call to WritePrinter не печатает
public class PrintRaw
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class DOC_INFO_1
{
[MarshalAs(UnmanagedType.LPStr)]
public string pDocName;
[MarshalAs(UnmanagedType.LPStr)]
public string pOutputFile;
[MarshalAs(UnmanagedType.LPStr)]
public string pDataType;
}
[DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi,
ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter,
IntPtr pd);
[DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
public static extern bool ClosePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi,
ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level,
[In, MarshalAs(UnmanagedType.LPStruct)] DOC_INFO_1 di);
[DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
public static extern bool EndDocPrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
public static extern bool StartPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
public static extern bool EndPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);
public void Print(String printerName, String filename)
{
IntPtr lhPrinter;
OpenPrinter(printerName, out lhPrinter, new IntPtr(0));
if (lhPrinter.ToInt32() == 0)
return; //Printer not found!!
var rawPrinter = new DOC_INFO_1() { pDocName = "My Document", pDataType = "RAW" };
StartDocPrinter(lhPrinter, 1, rawPrinter);
using (var b = new BinaryReader(File.Open(filename, FileMode.Open)))
{
var length = (int)b.BaseStream.Length;
const int bufferSize = 8192;
var numLoops = length/bufferSize;
var leftOver = length % bufferSize;
for (int i = 0; i < numLoops; i++)
{
var buffer = new byte[bufferSize];
int dwWritten;
b.Read(buffer, 0, bufferSize);
IntPtr unmanagedPointer = Marshal.AllocHGlobal(buffer.Length);
Marshal.Copy(buffer, 0, unmanagedPointer, buffer.Length);
WritePrinter(lhPrinter, unmanagedPointer, bufferSize, out dwWritten);
Marshal.FreeHGlobal(unmanagedPointer);
}
if (leftOver > 0)
{
var buffer = new byte[leftOver];
int dwWritten;
b.Read(buffer, 0, leftOver);
IntPtr unmanagedPointer = Marshal.AllocHGlobal(buffer.Length);
Marshal.Copy(buffer, 0, unmanagedPointer, buffer.Length);
var result = WritePrinter(lhPrinter, unmanagedPointer, leftOver, out dwWritten);
Marshal.FreeHGlobal(unmanagedPointer);
}
}
EndDocPrinter(lhPrinter);
ClosePrinter(lhPrinter);
}
}
MSDN говорит эти функции находятся в spoolss.dll –
Вызовы вызываются, и он даже возвращает дескриптор принтера, когда я даю ему настоящее имя принтера, поэтому я не думаю, что это проблема. Как я упоминал в вопросе, он даже терпит неудачу, когда я даю ему плохое имя принтера. Плюс большая часть этого кода от самого MSDN – spoof3r
В случае, если кому-то интересно, код взят со следующей ссылки. Я верю: https://vishalsbsinha.wordpress.com/2014/05/06/how-to-programmatically-c -net-print-a-pdf-file-direct-to-printer – slayernoah