Introduction
I did a post about printing to a zebra printer many moons ago (I had more hair back then). The Zebra printers I had (those are label printer if you really want to know) were connected to several windows xp machines. I use the EPL method because it is much faster than using windows printing on theses machines.
Yesterday I installed Windows 7 on those machines. And that caused the previous function to not work anymore. The problem is in the Createfile method and it not finding a handle anymore. You get this error when you try to print.
Invalid parameter name’ handle
As you can see in the forum topic with the same name. Some other people had the same problem.
Many labels later I found a solution.
The solution
After some searching and coming to my previous post to many times I found the SharpZebra library on codeplex. But for some strange reason that did not really work for my printer. It just printed nothing but did move the label one forward. So I looked at the code they used and converted it to VB.Net. After which I played with it for a while to get it to work.
I’m not sure which part made it work for me and my TLP2844 machines, since I tweaked it, but something did.
I also used this thread on MSDN.
I took out the Rawprinter class sharpzebra has. Which looks like this in VB.Net.
```vbnet Public Class RawPrinter Public Structure DOCINFO <MarshalAs(UnmanagedType.LPWStr)> Public DocumentName As String <MarshalAs(UnmanagedType.LPWStr)> Public OutputFile As String <MarshalAs(UnmanagedType.LPWStr)> Public DataType As String End Structure
<DllImport("winspool.drv", CharSet:=CharSet.Unicode, ExactSpelling:=False, CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function OpenPrinter(ByVal pPrinterName As String, ByRef phPrinter As IntPtr, ByVal pDefault As Integer) As Long
End Function
<DllImport("winspool.drv", CharSet:=CharSet.Unicode, ExactSpelling:=False, CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function StartDocPrinter(ByVal hPrinter As IntPtr, ByVal Level As Integer, ByRef pDocInfo As DOCINFO) As Long
End Function
<DllImport("winspool.drv", CharSet:=CharSet.Unicode, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function StartPagePrinter(ByVal hPrinter As IntPtr) As Long
End Function
<DllImport("winspool.drv", CharSet:=CharSet.Ansi, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function WritePrinter(ByVal hPrinter As IntPtr, ByVal data As String, ByVal buf As Integer, ByRef pcWritten As Integer) As Long
End Function
<DllImport("winspool.drv", CharSet:=CharSet.Unicode, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function EndPagePrinter(ByVal hPrinter As IntPtr) As Long
End Function
<DllImport("winspool.drv", CharSet:=CharSet.Unicode, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function EndDocPrinter(ByVal hPrinter As IntPtr) As Long
End Function
<DllImport("winspool.drv", CharSet:=CharSet.Unicode, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function ClosePrinter(ByVal hPrinter As IntPtr) As Long
End Function
Public Shared Sub SendToPrinter(ByVal printerJobName As String, ByVal rawStringToSendToThePrinter As String, ByVal printerNameAsDescribedByPrintManager As String)
Dim handleForTheOpenPrinter = New IntPtr()
Dim documentInformation = New DOCINFO()
Dim printerBytesWritten = 0
documentInformation.DocumentName = printerJobName
documentInformation.DataType = vbNullString
documentInformation.OutputFile = vbNullString
OpenPrinter(printerNameAsDescribedByPrintManager, handleForTheOpenPrinter, 0)
StartDocPrinter(handleForTheOpenPrinter, 1, documentInformation)
StartPagePrinter(handleForTheOpenPrinter)
WritePrinter(handleForTheOpenPrinter, rawStringToSendToThePrinter, rawStringToSendToThePrinter.Length, printerBytesWritten)
EndPagePrinter(handleForTheOpenPrinter)
EndDocPrinter(handleForTheOpenPrinter)
ClosePrinter(handleForTheOpenPrinter)
End Sub
End Class```
And this prints the commands I want directly to the rawprinter.
vbnet
Dim pText As New StringBuilder
pText.AppendLine("N") ' Start new document
pText.AppendLine("D15") ' Set Density
pText.AppendLine("S1") ' Set Speed
pText.AppendLine("A30,120,0,4,2,1,N,""print text""") ' print text
pText.AppendLine("B30,20,0,1,2,5,80,N,""print barcode""") ' print barcode
pText.AppendLine("P1") ' number of times to print
RawPrinter.SendToPrinter("zebra printing", pText.ToString, "\printerserverprintername") 'print the string
For some reason I never needed to pass the N or the P in the previous version. But now I do. sharpzebra was passing a nN and perhaps that was the cause for it not working. You can find all the EPL in the manual for your printer and you can even try it out via the driversoftware.
Conclusion
I like to thank the person(s) that made sharpzebra, it helped me a lot in solving this problem. And I hope the above will help someone else.