do not know if you solved this but here goes.
had a similar problem myself, solution was to use the printer driver to talk direct, that way it handles the talking to the printer on any port, and send lines with escape codes embedded. the other advantage of this is that using the windows drivers to print usually does not let you get at the full functionality of the printer (barcodes etc.).
there is an article on MS on using RawPrinterHelper to get a handle on the printer and write text direct. in the MS example it processes the write as a single document, which is slow if you write line by line as it opens and closes the printer each time so you would have to build a page. made a few modifications as (for me) a receipt printer is more of line oriented device there is no page size.
here is the MS link for the original:
http://support.microsoft.com/kb/322091
this is not perfect, still testing and more error trapping needed, if it does not open the printer it just consumes write no output.
here is the modified class for raw printing:
Imports System
Imports System.Drawing
Imports System.Drawing.Printing
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Imports System.IO
Public Class RawPrinterHelper
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Class DOCINFOA
<MarshalAs(UnmanagedType.LPStr)> _
Public pDocName As String
<MarshalAs(UnmanagedType.LPStr)> _
Public pOutputFile As String
<MarshalAs(UnmanagedType.LPStr)> _
Public pDataType As String
End Class
<DllImport("winspool.Drv", EntryPoint:="OpenPrinterA", SetLastError:=True, CharSet:=CharSet.Ansi, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function OpenPrinter(<MarshalAs(UnmanagedType.LPStr)> szPrinter As String, ByRef hPrinter As IntPtr, pd As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="ClosePrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function ClosePrinter(hPrinter As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="StartDocPrinterA", SetLastError:=True, CharSet:=CharSet.Ansi, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function StartDocPrinter(hPrinter As IntPtr, level As Int32, <[In](), MarshalAs(UnmanagedType.LPStruct)> di As DOCINFOA) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="EndDocPrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function EndDocPrinter(hPrinter As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="StartPagePrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function StartPagePrinter(hPrinter As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="EndPagePrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function EndPagePrinter(hPrinter As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="WritePrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function WritePrinter(hPrinter As IntPtr, pBytes As IntPtr, dwCount As Int32, ByRef dwWritten As Int32) As Boolean
End Function
Private hPrinter As New IntPtr(0)
Private di As New DOCINFOA()
Private PrinterOpen As Boolean = False
Public Sub OpenPrint(szPrinterName As String)
If PrinterOpen = False Then
di.pDocName = ".NET RAW Document"
di.pDataType = "RAW"
If OpenPrinter(szPrinterName.Normalize(), hPrinter, IntPtr.Zero) Then
If StartDocPrinter(hPrinter, 1, di) Then
If StartPagePrinter(hPrinter) Then
PrinterOpen = True
End If
End If
End If
End If
End Sub
Public Sub ClosePrint()
If PrinterOpen Then
EndPagePrinter(hPrinter)
EndDocPrinter(hPrinter)
ClosePrinter(hPrinter)
PrinterOpen = False
End If
End Sub
Public Function SendStringToPrinter(szPrinterName As String, szString As String) As Boolean
If PrinterOpen Then
Dim pBytes As IntPtr
Dim dwCount As Int32
Dim dwWritten As Int32 = 0
dwCount = szString.Length
pBytes = Marshal.StringToCoTaskMemAnsi(szString)
SendStringToPrinter = WritePrinter(hPrinter, pBytes, dwCount, dwWritten)
Marshal.FreeCoTaskMem(pBytes)
Else
SendStringToPrinter = False
End If
End Function
End Class
And an example usage my printers are all Epson so uses Epson escape sequences :
Public Class Form1
Public Const eClear As String = Chr(27) + "@"
Public Const eCentre As String = Chr(27) + Chr(97) + "1"
Public Const eLeft As String = Chr(27) + Chr(97) + "0"
Public Const eRight As String = Chr(27) + Chr(97) + "2"
Public Const eDrawer As String = eClear + Chr(27) + "p" + Chr(0) + ".}"
Public Const eCut As String = Chr(27) + "i" + vbCrLf
Public Const eSmlText As String = Chr(27) + "!" + Chr(1)
Public Const eNmlText As String = Chr(27) + "!" + Chr(0)
Public Const eInit As String = eNmlText + Chr(13) + Chr(27) + "c6" + Chr(1) + Chr(27) + "R3" + vbCrLf
Public Const eBigCharOn As String = Chr(27) + "!" + Chr(56)
Public Const eBigCharOff As String = Chr(27) + "!" + Chr(0)
Private prn As New RawPrinterHelper
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
StartPrint()
Print(eInit + eCentre + "Shop")
Print("Telephone")
Print("Web Address")
Print("Email Address")
Print("VAT Reg No:123 4567 89" + eLeft)
PrintDashes()
Print(eSmlText + "Tea T1 6.00")
PrintDashes()
Print(eSmlText + " Total: 6.00")
Print(" Paid Cash: 6.00")
Print(eCentre + "Thank You For Your Support!" + eLeft)
Print(vbLf + vbLf + vbLf + vbLf + vbLf + eCut + eDrawer)
EndPrint()
StartPrint()
Print(eCentre + "Thank You For Your Support!" + eLeft)
Print(vbLf + vbLf + vbLf + vbLf + vbLf + eCut)
EndPrint()
End Sub
Private PrintBuffer As String
Public Sub StartPrint()
PrintBuffer = ""
prn.OpenPrint("EPSON TM-T20 Receipt")
End Sub
Public Sub Print(Line As String)
prn.SendStringToPrinter("EPSON TM-T20 Receipt", Line + vbLf)
End Sub
Public Sub PrintDashes()
Print(eLeft + eNmlText + "-".PadRight(42, "-"))
End Sub
Public Sub EndPrint()
prn.ClosePrint()
End Sub
End Class
means you format strings manually, pad item names out with spaces to position cash values but i find that easier...
code block lang changed fom xml to vb