java和打印机通信,通过Windows驱动程序与热敏打印机进行双向通信
我需要開發一個應用程序來打印熱敏打印機,如Epson ESC / POS協議或ZPL Zebra協議 . 我可以使用網絡打印機,串口打印機以及窗口的假脫機打印機將原始代碼寫入打印機 . 當我需要“查詢”prnter以獲取其狀態(準備,錯誤,紙張結束等)時,我的麻煩開始了,在這種情況下我需要反向通信,我發送一個特殊命令,打印機回答一些狀態字節 . 一切都很清楚......使用網絡/插座打印機或串口打印機......用Windows打印機我無法理解如何讀取打印機狀態...
有什么解決方案嗎?
UPDATE
按照Hans的建議,我正在嘗試使用Windows API讀取打印機 . 這是我用ESC / POS協議測試的 .
public class WinPrinter
{
// Structure and API declarions:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class DOCINFOA
{
[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)] DOCINFOA 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);
[DllImport("winspool.Drv", EntryPoint = "ReadPrinter", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool ReadPrinter(IntPtr hPrinter, [MarshalAs(UnmanagedType.LPStr)] StringBuilder pBytes, Int32 dwCount, out Int32 dwNReadBytes);
public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount)
{
Int32 dwError = 0, dwWritten = 0;
IntPtr hPrinter = new IntPtr(0);
DOCINFOA di = new DOCINFOA();
bool bSuccess = false; // Assume failure unless you specifically succeed.
di.pDocName = "My C#.NET RAW Document";
di.pDataType = "RAW";
// Open the printer.
if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero))
{
// Start a document.
if (StartDocPrinter(hPrinter, 1, di))
{
// Start a page.
if (StartPagePrinter(hPrinter))
{
// Write your bytes.
bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);
EndPagePrinter(hPrinter);
}
EndDocPrinter(hPrinter);
}
string reaDstrinG = "";
Int32 buf = 0;
Int32 pcRead;
System.Text.StringBuilder sb = new System.Text.StringBuilder();
bool read = ReadPrinter(hPrinter, sb.Append(reaDstrinG), buf, out pcRead);
ClosePrinter(hPrinter);
}
// If you did not succeed, GetLastError may give more information
// about why not.
if (bSuccess == false)
{
dwError = Marshal.GetLastWin32Error();
}
return bSuccess;
}
static void Main(string[] args)
{
String test = "\u0010\u0004\u0001";
IntPtr pBytes=Marshal.StringToCoTaskMemAnsi(test);
Int32 dwCount = test.Length;
WinPrinter.SendBytesToPrinter("BIXOLON SRP-350 (Copia 1)",pBytes,dwCount);
}
}
我確信“\ u0010 \ u0004 \ u0001”(DLE EOT 1)是在ESCPOS協議中請求打印機狀態的推薦,我用串行連接的同一臺打印機測試它,我得到一個狀態字節 .
但是使用上面的代碼,我總是從ReadPrinter方法得到錯誤 . 我檢查了打印機端口是否啟用了“雙向”選項,我也嘗試過沒有假脫機程序選項 .
總結
以上是生活随笔為你收集整理的java和打印机通信,通过Windows驱动程序与热敏打印机进行双向通信的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: xml批量修改php,通过php修改xm
- 下一篇: php调用for循环函数吗,我需要将“函