Im using a tweaked version of the RawPrinterHelper.cs class to print directly to a zebra printer. All is fine until I try and print something containing unicode text, the print still happens but the unicode characters are displayed as question marks. The font Im using on the printer is a unicode code one and I can print unicode on the printer via one of the Zebra utility programs. I thought the problem may have been in the SendStringToPrinter method with the call to Marshal.StringToCoTaskMemAnsi(szString), so I changed it to Marshal.StringToCoTaskMemUni(szString) but doing that caused the printer to fail to print, but with its data light on.
My version of RawPrinterHelper.cs is below:
using
System;using
System.IO;using
System.Drawing.Printing;using
System.Runtime.InteropServices;namespace
Printing2
{
classRawPrinterHelper2
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
publicstructDOCINFOW
{
[MarshalAs(UnmanagedType.LPWStr)]
publicstring pDocName;
[MarshalAs(UnmanagedType.LPWStr)]
publicstring pOutputFile;
[MarshalAs(UnmanagedType.LPWStr)]
publicstring pDataType;
}
[DllImport("winspool.Drv", EntryPoint = "OpenPrinterW", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
publicstaticexternbool OpenPrinter(string src, refIntPtr hPrinter, long pd);
[DllImport("winspool.Drv", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
publicstaticexternbool ClosePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartDocPrinterW", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
publicstaticexternbool StartDocPrinter(IntPtr hPrinter, int level, refRawPrinterHelper2.DOCINFOW pDI);
[DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
publicstaticexternbool EndDocPrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
publicstaticexternbool StartPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
publicstaticexternbool EndPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
publicstaticexternbool WritePrinter(IntPtr hPrinter, IntPtr pBytes, int dwCount, refint dwWritten);
publicstaticbool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount)
{
IntPtr hPrinter = System.IntPtr.Zero;
Int32 dwError;
DOCINFOW di = newDOCINFOW();
Int32 dwWritten = 0;
bool bSuccess;
di.pDocName = "My Document";
di.pDataType = "RAW";
bSuccess = false;
if (OpenPrinter(szPrinterName, ref hPrinter, 0))
{
if (StartDocPrinter(hPrinter, 1, ref di))
{
if (StartPagePrinter(hPrinter))
{
bSuccess = WritePrinter(hPrinter, pBytes, dwCount, ref dwWritten);
EndPagePrinter(hPrinter);
}
EndDocPrinter(hPrinter);
}
ClosePrinter(hPrinter);
}
if (bSuccess == false)
{
dwError = Marshal.GetLastWin32Error();
}
return bSuccess;
}
publicstaticbool SendFileToPrinter(string szPrinterName, string szFileName)
{
FileStream stream1 = newFileStream(szFileName, FileMode.Open);
BinaryReader reader1 = newBinaryReader(stream1);
byte[] buffer1 = newbyte[((int)stream1.Length) + 1];
buffer1 = reader1.ReadBytes((int)stream1.Length);
IntPtr ptr1 = Marshal.AllocCoTaskMem((int)stream1.Length);
Marshal.Copy(buffer1, 0, ptr1, (int)stream1.Length);
bool flag1 = RawPrinterHelper2.SendBytesToPrinter(szPrinterName, ptr1, (int)stream1.Length);
Marshal.FreeCoTaskMem(ptr1);
return flag1;
}
publicstaticvoid SendStringToPrinter(string szPrinterName, string szString)
{
IntPtr pBytes;
Int32 dwCount;
dwCount = szString.Length;
pBytes = Marshal.StringToCoTaskMemAnsi(szString);
SendBytesToPrinter(szPrinterName, pBytes, dwCount);
Marshal.FreeCoTaskMem(pBytes);
}
}
}