C# 将打印作业从PuTTY发送到Zebra ZXP 3 SDK(非.zpl打印机)
我拥有的是一个通过PuTTY(SSH客户端)访问的病历数据库。卡本身将仅具有客户名称、条形码格式的记录编号(仍在确定要使用的条形码类型)和客户注册日期 1) 对于Zebra条形码标签打印机或与激光打印机(如HP或Brother)兼容的原始格式,我们可以将数据输出为.zpl。 2) ZXP3SDK将接受什么输出? 3) 是否可以使用诸如RedMon之类的命令行将SDK设置为等待并接受来自它的数据 这些卡片本身将只有打印的数据,没有磁条、智能芯片、层压板或类似的东西C# 将打印作业从PuTTY发送到Zebra ZXP 3 SDK(非.zpl打印机),c#,putty,zebra-printers,redmon,C#,Putty,Zebra Printers,Redmon,我拥有的是一个通过PuTTY(SSH客户端)访问的病历数据库。卡本身将仅具有客户名称、条形码格式的记录编号(仍在确定要使用的条形码类型)和客户注册日期 1) 对于Zebra条形码标签打印机或与激光打印机(如HP或Brother)兼容的原始格式,我们可以将数据输出为.zpl。 2) ZXP3SDK将接受什么输出? 3) 是否可以使用诸如RedMon之类的命令行将SDK设置为等待并接受来自它的数据 这些卡片本身将只有打印的数据,没有磁条、智能芯片、层压板或类似的东西 Mahalo。我不建议使用Red
Mahalo。我不建议使用RedMon和SDK,因为它们都不是你想要做的事情所必需的,而且它们都是时间吸血鬼。相反,我会编写一个小的Windows窗体应用程序,它监听TCP端口以接收打印作业并将其发送到使用Zebra驱动程序的标准打印机 让腮腺炎应用程序通过VT100中的远程打印支持发送XML文档。我使用的示例如下:
^[[5i
<patient>
<name first="John" last="Smith" />
<mrn>A04390503</mrn>
<dob>1991-03-12</dob>
</patient>
^[[4i
trayaapplicationcontext.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PassThroughPrinterTest
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new TrayApplicationContext());
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PassThroughPrinterTest
{
class TrayApplicationContext : ApplicationContext
{
private NotifyIcon trayIcon;
private PrintListener listener;
private PrintHandler handler;
public TrayApplicationContext()
{
this.trayIcon = new NotifyIcon()
{
Text = "Card Formatter",
Icon = Properties.Resources.AppIcon,
ContextMenu = new ContextMenu()
{
MenuItems =
{
new MenuItem("Print Options...", miPrintOptions_Click),
new MenuItem("Exit", miExit_Click)
}
},
Visible = true
};
this.handler = new PrintHandler();
this.listener = new PrintListener(9101);
this.listener.PrintDataReceived += this.handler.HandlePrintData;
}
private void miPrintOptions_Click(object sender, EventArgs args)
{
// TODO: add configuration and options to avoid having to hard code
// the printer name in PrintHandler.cs
MessageBox.Show("Options");
}
private void miExit_Click(object sender, EventArgs args)
{
Application.Exit();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
trayIcon.Dispose();
}
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Printing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
namespace PassThroughPrinterTest
{
partial class PrintHandler : Form
{
public PrintHandler()
{
InitializeComponent();
}
public void HandlePrintData(object sender, PrintDataReceivedEventArgs args)
{
if (this.InvokeRequired)
{
this.Invoke(new EventHandler<PrintDataReceivedEventArgs>(HandlePrintData), sender, args);
return;
}
this.Show();
var sXml = Encoding.UTF8.GetString(args.PrintData);
this.PrintCard(XDocument.Parse(sXml));
this.Hide();
}
private void PrintCard(XDocument xDocument)
{
var nameElement = xDocument.Root.Element("name");
var lastName = nameElement.Attribute("last").Value;
var firstName = nameElement.Attribute("first").Value;
var mrn = xDocument.Root.Element("mrn").Value;
var printDoc = new PrintDocument()
{
PrinterSettings = new PrinterSettings()
{
PrinterName = "Adobe PDF"
},
DocumentName = "Patient ID Card"
};
var cardPaperSize = new PaperSize("Card", 337, 213) { RawKind = (int)PaperKind.Custom };
printDoc.DefaultPageSettings.PaperSize = cardPaperSize;
printDoc.PrinterSettings.DefaultPageSettings.PaperSize = cardPaperSize;
printDoc.PrintPage += (s, e) =>
{
var gfx = e.Graphics;
// print the text information
var fArial12 = new Font("Arial", 12);
gfx.DrawString(lastName, fArial12, Brushes.Black, new RectangleF(25, 25, 200, 75));
gfx.DrawString(firstName, fArial12, Brushes.Black, new RectangleF(25, 100, 200, 75));
// add a code39 barcode using a barcode font
// http://www.idautomation.com/free-barcode-products/code39-font/
// var fCode39 = new Font("IDAutomationHC39M", 12);
// gfx.DrawString("(" + mrn + ")", fArial12, Brushes.Black, new RectangleF(25, 200, 200, 75));
// or by using a barcode library
// https://barcoderender.codeplex.com/
// var barcode = BarcodeDrawFactory.Code128WithChecksum.Draw(mrn, 20, 2);
// gfx.DrawImage(barcode, 50, 200);
e.HasMorePages = false;
};
printDoc.Print();
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace PassThroughPrinterTest
{
sealed class PrintListener : IDisposable
{
private TcpListener listener;
public event EventHandler<PrintDataReceivedEventArgs> PrintDataReceived;
public PrintListener(int port)
{
this.listener = new TcpListener(IPAddress.Loopback, port);
this.listener.Start();
this.listener.BeginAcceptTcpClient(listener_AcceptClient, null);
}
public void Dispose()
{
this.listener.Stop();
}
private void listener_AcceptClient(IAsyncResult iar)
{
TcpClient client = null;
bool isStopped = false;
try
{
client = this.listener.EndAcceptTcpClient(iar);
}
catch (ObjectDisposedException)
{
// this will occur in graceful shutdown
isStopped = true;
return;
}
finally
{
if (!isStopped)
{
this.listener.BeginAcceptTcpClient(listener_AcceptClient, null);
}
}
Debug.Assert(client != null);
try
{
byte[] printData;
using (var clientStream = client.GetStream())
using (var buffer = new MemoryStream())
{
clientStream.CopyTo(buffer);
printData = buffer.ToArray();
}
OnPrintDataReceived(printData);
}
catch
{
// TODO: add logging and error handling for network issues or processing issues
throw;
}
finally
{
client.Close();
}
}
private void OnPrintDataReceived(byte[] printData)
{
var handler = PrintDataReceived;
if (handler != null)
{
handler(this, new PrintDataReceivedEventArgs(printData));
}
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PassThroughPrinterTest
{
class TrayApplicationContext : ApplicationContext
{
private NotifyIcon trayIcon;
private PrintListener listener;
private PrintHandler handler;
public TrayApplicationContext()
{
this.trayIcon = new NotifyIcon()
{
Text = "Card Formatter",
Icon = Properties.Resources.AppIcon,
ContextMenu = new ContextMenu()
{
MenuItems =
{
new MenuItem("Print Options...", miPrintOptions_Click),
new MenuItem("Exit", miExit_Click)
}
},
Visible = true
};
this.handler = new PrintHandler();
this.listener = new PrintListener(9101);
this.listener.PrintDataReceived += this.handler.HandlePrintData;
}
private void miPrintOptions_Click(object sender, EventArgs args)
{
// TODO: add configuration and options to avoid having to hard code
// the printer name in PrintHandler.cs
MessageBox.Show("Options");
}
private void miExit_Click(object sender, EventArgs args)
{
Application.Exit();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
listener.Dispose();
trayIcon.Dispose();
}
}
}
}
using System;
namespace PassThroughPrinterTest
{
class PrintDataReceivedEventArgs : EventArgs
{
public byte[] PrintData { get; set; }
public PrintDataReceivedEventArgs(byte[] data)
{
if (data == null)
throw new ArgumentNullException("data");
this.PrintData = data;
}
}
}
PrintHandler.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PassThroughPrinterTest
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new TrayApplicationContext());
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PassThroughPrinterTest
{
class TrayApplicationContext : ApplicationContext
{
private NotifyIcon trayIcon;
private PrintListener listener;
private PrintHandler handler;
public TrayApplicationContext()
{
this.trayIcon = new NotifyIcon()
{
Text = "Card Formatter",
Icon = Properties.Resources.AppIcon,
ContextMenu = new ContextMenu()
{
MenuItems =
{
new MenuItem("Print Options...", miPrintOptions_Click),
new MenuItem("Exit", miExit_Click)
}
},
Visible = true
};
this.handler = new PrintHandler();
this.listener = new PrintListener(9101);
this.listener.PrintDataReceived += this.handler.HandlePrintData;
}
private void miPrintOptions_Click(object sender, EventArgs args)
{
// TODO: add configuration and options to avoid having to hard code
// the printer name in PrintHandler.cs
MessageBox.Show("Options");
}
private void miExit_Click(object sender, EventArgs args)
{
Application.Exit();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
trayIcon.Dispose();
}
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Printing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
namespace PassThroughPrinterTest
{
partial class PrintHandler : Form
{
public PrintHandler()
{
InitializeComponent();
}
public void HandlePrintData(object sender, PrintDataReceivedEventArgs args)
{
if (this.InvokeRequired)
{
this.Invoke(new EventHandler<PrintDataReceivedEventArgs>(HandlePrintData), sender, args);
return;
}
this.Show();
var sXml = Encoding.UTF8.GetString(args.PrintData);
this.PrintCard(XDocument.Parse(sXml));
this.Hide();
}
private void PrintCard(XDocument xDocument)
{
var nameElement = xDocument.Root.Element("name");
var lastName = nameElement.Attribute("last").Value;
var firstName = nameElement.Attribute("first").Value;
var mrn = xDocument.Root.Element("mrn").Value;
var printDoc = new PrintDocument()
{
PrinterSettings = new PrinterSettings()
{
PrinterName = "Adobe PDF"
},
DocumentName = "Patient ID Card"
};
var cardPaperSize = new PaperSize("Card", 337, 213) { RawKind = (int)PaperKind.Custom };
printDoc.DefaultPageSettings.PaperSize = cardPaperSize;
printDoc.PrinterSettings.DefaultPageSettings.PaperSize = cardPaperSize;
printDoc.PrintPage += (s, e) =>
{
var gfx = e.Graphics;
// print the text information
var fArial12 = new Font("Arial", 12);
gfx.DrawString(lastName, fArial12, Brushes.Black, new RectangleF(25, 25, 200, 75));
gfx.DrawString(firstName, fArial12, Brushes.Black, new RectangleF(25, 100, 200, 75));
// add a code39 barcode using a barcode font
// http://www.idautomation.com/free-barcode-products/code39-font/
// var fCode39 = new Font("IDAutomationHC39M", 12);
// gfx.DrawString("(" + mrn + ")", fArial12, Brushes.Black, new RectangleF(25, 200, 200, 75));
// or by using a barcode library
// https://barcoderender.codeplex.com/
// var barcode = BarcodeDrawFactory.Code128WithChecksum.Draw(mrn, 20, 2);
// gfx.DrawImage(barcode, 50, 200);
e.HasMorePages = false;
};
printDoc.Print();
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace PassThroughPrinterTest
{
sealed class PrintListener : IDisposable
{
private TcpListener listener;
public event EventHandler<PrintDataReceivedEventArgs> PrintDataReceived;
public PrintListener(int port)
{
this.listener = new TcpListener(IPAddress.Loopback, port);
this.listener.Start();
this.listener.BeginAcceptTcpClient(listener_AcceptClient, null);
}
public void Dispose()
{
this.listener.Stop();
}
private void listener_AcceptClient(IAsyncResult iar)
{
TcpClient client = null;
bool isStopped = false;
try
{
client = this.listener.EndAcceptTcpClient(iar);
}
catch (ObjectDisposedException)
{
// this will occur in graceful shutdown
isStopped = true;
return;
}
finally
{
if (!isStopped)
{
this.listener.BeginAcceptTcpClient(listener_AcceptClient, null);
}
}
Debug.Assert(client != null);
try
{
byte[] printData;
using (var clientStream = client.GetStream())
using (var buffer = new MemoryStream())
{
clientStream.CopyTo(buffer);
printData = buffer.ToArray();
}
OnPrintDataReceived(printData);
}
catch
{
// TODO: add logging and error handling for network issues or processing issues
throw;
}
finally
{
client.Close();
}
}
private void OnPrintDataReceived(byte[] printData)
{
var handler = PrintDataReceived;
if (handler != null)
{
handler(this, new PrintDataReceivedEventArgs(printData));
}
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PassThroughPrinterTest
{
class TrayApplicationContext : ApplicationContext
{
private NotifyIcon trayIcon;
private PrintListener listener;
private PrintHandler handler;
public TrayApplicationContext()
{
this.trayIcon = new NotifyIcon()
{
Text = "Card Formatter",
Icon = Properties.Resources.AppIcon,
ContextMenu = new ContextMenu()
{
MenuItems =
{
new MenuItem("Print Options...", miPrintOptions_Click),
new MenuItem("Exit", miExit_Click)
}
},
Visible = true
};
this.handler = new PrintHandler();
this.listener = new PrintListener(9101);
this.listener.PrintDataReceived += this.handler.HandlePrintData;
}
private void miPrintOptions_Click(object sender, EventArgs args)
{
// TODO: add configuration and options to avoid having to hard code
// the printer name in PrintHandler.cs
MessageBox.Show("Options");
}
private void miExit_Click(object sender, EventArgs args)
{
Application.Exit();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
listener.Dispose();
trayIcon.Dispose();
}
}
}
}
using System;
namespace PassThroughPrinterTest
{
class PrintDataReceivedEventArgs : EventArgs
{
public byte[] PrintData { get; set; }
public PrintDataReceivedEventArgs(byte[] data)
{
if (data == null)
throw new ArgumentNullException("data");
this.PrintData = data;
}
}
}
trayaapplicationcontext.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PassThroughPrinterTest
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new TrayApplicationContext());
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PassThroughPrinterTest
{
class TrayApplicationContext : ApplicationContext
{
private NotifyIcon trayIcon;
private PrintListener listener;
private PrintHandler handler;
public TrayApplicationContext()
{
this.trayIcon = new NotifyIcon()
{
Text = "Card Formatter",
Icon = Properties.Resources.AppIcon,
ContextMenu = new ContextMenu()
{
MenuItems =
{
new MenuItem("Print Options...", miPrintOptions_Click),
new MenuItem("Exit", miExit_Click)
}
},
Visible = true
};
this.handler = new PrintHandler();
this.listener = new PrintListener(9101);
this.listener.PrintDataReceived += this.handler.HandlePrintData;
}
private void miPrintOptions_Click(object sender, EventArgs args)
{
// TODO: add configuration and options to avoid having to hard code
// the printer name in PrintHandler.cs
MessageBox.Show("Options");
}
private void miExit_Click(object sender, EventArgs args)
{
Application.Exit();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
trayIcon.Dispose();
}
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Printing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
namespace PassThroughPrinterTest
{
partial class PrintHandler : Form
{
public PrintHandler()
{
InitializeComponent();
}
public void HandlePrintData(object sender, PrintDataReceivedEventArgs args)
{
if (this.InvokeRequired)
{
this.Invoke(new EventHandler<PrintDataReceivedEventArgs>(HandlePrintData), sender, args);
return;
}
this.Show();
var sXml = Encoding.UTF8.GetString(args.PrintData);
this.PrintCard(XDocument.Parse(sXml));
this.Hide();
}
private void PrintCard(XDocument xDocument)
{
var nameElement = xDocument.Root.Element("name");
var lastName = nameElement.Attribute("last").Value;
var firstName = nameElement.Attribute("first").Value;
var mrn = xDocument.Root.Element("mrn").Value;
var printDoc = new PrintDocument()
{
PrinterSettings = new PrinterSettings()
{
PrinterName = "Adobe PDF"
},
DocumentName = "Patient ID Card"
};
var cardPaperSize = new PaperSize("Card", 337, 213) { RawKind = (int)PaperKind.Custom };
printDoc.DefaultPageSettings.PaperSize = cardPaperSize;
printDoc.PrinterSettings.DefaultPageSettings.PaperSize = cardPaperSize;
printDoc.PrintPage += (s, e) =>
{
var gfx = e.Graphics;
// print the text information
var fArial12 = new Font("Arial", 12);
gfx.DrawString(lastName, fArial12, Brushes.Black, new RectangleF(25, 25, 200, 75));
gfx.DrawString(firstName, fArial12, Brushes.Black, new RectangleF(25, 100, 200, 75));
// add a code39 barcode using a barcode font
// http://www.idautomation.com/free-barcode-products/code39-font/
// var fCode39 = new Font("IDAutomationHC39M", 12);
// gfx.DrawString("(" + mrn + ")", fArial12, Brushes.Black, new RectangleF(25, 200, 200, 75));
// or by using a barcode library
// https://barcoderender.codeplex.com/
// var barcode = BarcodeDrawFactory.Code128WithChecksum.Draw(mrn, 20, 2);
// gfx.DrawImage(barcode, 50, 200);
e.HasMorePages = false;
};
printDoc.Print();
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace PassThroughPrinterTest
{
sealed class PrintListener : IDisposable
{
private TcpListener listener;
public event EventHandler<PrintDataReceivedEventArgs> PrintDataReceived;
public PrintListener(int port)
{
this.listener = new TcpListener(IPAddress.Loopback, port);
this.listener.Start();
this.listener.BeginAcceptTcpClient(listener_AcceptClient, null);
}
public void Dispose()
{
this.listener.Stop();
}
private void listener_AcceptClient(IAsyncResult iar)
{
TcpClient client = null;
bool isStopped = false;
try
{
client = this.listener.EndAcceptTcpClient(iar);
}
catch (ObjectDisposedException)
{
// this will occur in graceful shutdown
isStopped = true;
return;
}
finally
{
if (!isStopped)
{
this.listener.BeginAcceptTcpClient(listener_AcceptClient, null);
}
}
Debug.Assert(client != null);
try
{
byte[] printData;
using (var clientStream = client.GetStream())
using (var buffer = new MemoryStream())
{
clientStream.CopyTo(buffer);
printData = buffer.ToArray();
}
OnPrintDataReceived(printData);
}
catch
{
// TODO: add logging and error handling for network issues or processing issues
throw;
}
finally
{
client.Close();
}
}
private void OnPrintDataReceived(byte[] printData)
{
var handler = PrintDataReceived;
if (handler != null)
{
handler(this, new PrintDataReceivedEventArgs(printData));
}
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PassThroughPrinterTest
{
class TrayApplicationContext : ApplicationContext
{
private NotifyIcon trayIcon;
private PrintListener listener;
private PrintHandler handler;
public TrayApplicationContext()
{
this.trayIcon = new NotifyIcon()
{
Text = "Card Formatter",
Icon = Properties.Resources.AppIcon,
ContextMenu = new ContextMenu()
{
MenuItems =
{
new MenuItem("Print Options...", miPrintOptions_Click),
new MenuItem("Exit", miExit_Click)
}
},
Visible = true
};
this.handler = new PrintHandler();
this.listener = new PrintListener(9101);
this.listener.PrintDataReceived += this.handler.HandlePrintData;
}
private void miPrintOptions_Click(object sender, EventArgs args)
{
// TODO: add configuration and options to avoid having to hard code
// the printer name in PrintHandler.cs
MessageBox.Show("Options");
}
private void miExit_Click(object sender, EventArgs args)
{
Application.Exit();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
listener.Dispose();
trayIcon.Dispose();
}
}
}
}
using System;
namespace PassThroughPrinterTest
{
class PrintDataReceivedEventArgs : EventArgs
{
public byte[] PrintData { get; set; }
public PrintDataReceivedEventArgs(byte[] data)
{
if (data == null)
throw new ArgumentNullException("data");
this.PrintData = data;
}
}
}
PrintDataReceivedEventArgs.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PassThroughPrinterTest
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new TrayApplicationContext());
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PassThroughPrinterTest
{
class TrayApplicationContext : ApplicationContext
{
private NotifyIcon trayIcon;
private PrintListener listener;
private PrintHandler handler;
public TrayApplicationContext()
{
this.trayIcon = new NotifyIcon()
{
Text = "Card Formatter",
Icon = Properties.Resources.AppIcon,
ContextMenu = new ContextMenu()
{
MenuItems =
{
new MenuItem("Print Options...", miPrintOptions_Click),
new MenuItem("Exit", miExit_Click)
}
},
Visible = true
};
this.handler = new PrintHandler();
this.listener = new PrintListener(9101);
this.listener.PrintDataReceived += this.handler.HandlePrintData;
}
private void miPrintOptions_Click(object sender, EventArgs args)
{
// TODO: add configuration and options to avoid having to hard code
// the printer name in PrintHandler.cs
MessageBox.Show("Options");
}
private void miExit_Click(object sender, EventArgs args)
{
Application.Exit();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
trayIcon.Dispose();
}
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Printing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
namespace PassThroughPrinterTest
{
partial class PrintHandler : Form
{
public PrintHandler()
{
InitializeComponent();
}
public void HandlePrintData(object sender, PrintDataReceivedEventArgs args)
{
if (this.InvokeRequired)
{
this.Invoke(new EventHandler<PrintDataReceivedEventArgs>(HandlePrintData), sender, args);
return;
}
this.Show();
var sXml = Encoding.UTF8.GetString(args.PrintData);
this.PrintCard(XDocument.Parse(sXml));
this.Hide();
}
private void PrintCard(XDocument xDocument)
{
var nameElement = xDocument.Root.Element("name");
var lastName = nameElement.Attribute("last").Value;
var firstName = nameElement.Attribute("first").Value;
var mrn = xDocument.Root.Element("mrn").Value;
var printDoc = new PrintDocument()
{
PrinterSettings = new PrinterSettings()
{
PrinterName = "Adobe PDF"
},
DocumentName = "Patient ID Card"
};
var cardPaperSize = new PaperSize("Card", 337, 213) { RawKind = (int)PaperKind.Custom };
printDoc.DefaultPageSettings.PaperSize = cardPaperSize;
printDoc.PrinterSettings.DefaultPageSettings.PaperSize = cardPaperSize;
printDoc.PrintPage += (s, e) =>
{
var gfx = e.Graphics;
// print the text information
var fArial12 = new Font("Arial", 12);
gfx.DrawString(lastName, fArial12, Brushes.Black, new RectangleF(25, 25, 200, 75));
gfx.DrawString(firstName, fArial12, Brushes.Black, new RectangleF(25, 100, 200, 75));
// add a code39 barcode using a barcode font
// http://www.idautomation.com/free-barcode-products/code39-font/
// var fCode39 = new Font("IDAutomationHC39M", 12);
// gfx.DrawString("(" + mrn + ")", fArial12, Brushes.Black, new RectangleF(25, 200, 200, 75));
// or by using a barcode library
// https://barcoderender.codeplex.com/
// var barcode = BarcodeDrawFactory.Code128WithChecksum.Draw(mrn, 20, 2);
// gfx.DrawImage(barcode, 50, 200);
e.HasMorePages = false;
};
printDoc.Print();
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace PassThroughPrinterTest
{
sealed class PrintListener : IDisposable
{
private TcpListener listener;
public event EventHandler<PrintDataReceivedEventArgs> PrintDataReceived;
public PrintListener(int port)
{
this.listener = new TcpListener(IPAddress.Loopback, port);
this.listener.Start();
this.listener.BeginAcceptTcpClient(listener_AcceptClient, null);
}
public void Dispose()
{
this.listener.Stop();
}
private void listener_AcceptClient(IAsyncResult iar)
{
TcpClient client = null;
bool isStopped = false;
try
{
client = this.listener.EndAcceptTcpClient(iar);
}
catch (ObjectDisposedException)
{
// this will occur in graceful shutdown
isStopped = true;
return;
}
finally
{
if (!isStopped)
{
this.listener.BeginAcceptTcpClient(listener_AcceptClient, null);
}
}
Debug.Assert(client != null);
try
{
byte[] printData;
using (var clientStream = client.GetStream())
using (var buffer = new MemoryStream())
{
clientStream.CopyTo(buffer);
printData = buffer.ToArray();
}
OnPrintDataReceived(printData);
}
catch
{
// TODO: add logging and error handling for network issues or processing issues
throw;
}
finally
{
client.Close();
}
}
private void OnPrintDataReceived(byte[] printData)
{
var handler = PrintDataReceived;
if (handler != null)
{
handler(this, new PrintDataReceivedEventArgs(printData));
}
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PassThroughPrinterTest
{
class TrayApplicationContext : ApplicationContext
{
private NotifyIcon trayIcon;
private PrintListener listener;
private PrintHandler handler;
public TrayApplicationContext()
{
this.trayIcon = new NotifyIcon()
{
Text = "Card Formatter",
Icon = Properties.Resources.AppIcon,
ContextMenu = new ContextMenu()
{
MenuItems =
{
new MenuItem("Print Options...", miPrintOptions_Click),
new MenuItem("Exit", miExit_Click)
}
},
Visible = true
};
this.handler = new PrintHandler();
this.listener = new PrintListener(9101);
this.listener.PrintDataReceived += this.handler.HandlePrintData;
}
private void miPrintOptions_Click(object sender, EventArgs args)
{
// TODO: add configuration and options to avoid having to hard code
// the printer name in PrintHandler.cs
MessageBox.Show("Options");
}
private void miExit_Click(object sender, EventArgs args)
{
Application.Exit();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
listener.Dispose();
trayIcon.Dispose();
}
}
}
}
using System;
namespace PassThroughPrinterTest
{
class PrintDataReceivedEventArgs : EventArgs
{
public byte[] PrintData { get; set; }
public PrintDataReceivedEventArgs(byte[] data)
{
if (data == null)
throw new ArgumentNullException("data");
this.PrintData = data;
}
}
}
@肯怀特感谢您的好意指导。我做了一个重要的编辑。如果它仍然不正常,你能提供建议吗?我确实想遵守指导原则,但也会承认,就问题本身而言,我有点绝望。编辑得很好!更清楚你在问什么+1、谢谢。:-)@KenWhite感谢Ken在我努力解决这个问题时的耐心和帮助。@Mitch-我来试试看它是如何运作的。将需要让实际的数据库管理员在他们结束时进行清理。它可能仍然设置为output.zpl,因为他们在等待我找到解决方案(我希望您刚刚提供了解决方案)。@Mitch必须与数据库管理员合作,将这些数据打印为XML。同时,我从未使用过C#,因此我不确定如何在登录时运行它,因为是否有命令行,或者是否需要使用Visual Studio编译此文件,或者是否有一个.exe埋在此处?