Barkod Printer, Seri Port, USB, C# üzerine… – 3

Bundan önceki ilk 2 makalede sırasıyla Barkod yazıcılara ve C# içinden erişime değinmiştik. Ülkemizde yaygın olarak bulunan Zebra ve Argox yazıcılar için, barkod komut dili olan PPLA PPLB ZPL gibi diller ile tasarım yapmayı ve bu tasarımları barkod yazıcıya göndermeyi anlatmıştım.

Bu makalede ise  C# içinden  USB ile bağlı olan yazıcıya, data göndermek üzere gliştirilmiş kütüphaneyi ve C# içinden kullanımını göstereceğim.

aşağıdaki kodu DirectPrint.cs olarak kaydedip, var olan projenize item olarak eklemeniz yeterlidir.

// DirectPrint.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;

namespace VYP
{
	public class RawPrinterHelper
	{
		// 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);

		// SendBytesToPrinter()
		// When the function is given a printer name and an unmanaged array
		// of bytes, the function sends those bytes to the print queue.
		// Returns true on success, false on failure.
		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 = "Mavis RAW Document (Barcode)";
			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);
				}
				ClosePrinter(hPrinter);
			}
			// If you did not succeed, GetLastError may give more information
			// about why not.
			if (bSuccess == false)
			{
				dwError = Marshal.GetLastWin32Error();
			}
			return bSuccess;
		}

		public static bool SendFileToPrinter(string szPrinterName, string szFileName)
		{
			// Open the file.
			FileStream fs = new FileStream(szFileName, FileMode.Open);
			// Create a BinaryReader on the file.
			BinaryReader br = new BinaryReader(fs);
			// Dim an array of bytes big enough to hold the file's contents.
			Byte[] bytes = new Byte[fs.Length];
			bool bSuccess = false;
			// Your unmanaged pointer.
			IntPtr pUnmanagedBytes = new IntPtr(0);
			int nLength;

			nLength = Convert.ToInt32(fs.Length);
			// Read the contents of the file into the array.
			bytes = br.ReadBytes(nLength);
			// Allocate some unmanaged memory for those bytes.
			pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);
			// Copy the managed byte array into the unmanaged array.
			Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength);
			// Send the unmanaged bytes to the printer.
			bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength);
			// Free the unmanaged memory that you allocated earlier.
			Marshal.FreeCoTaskMem(pUnmanagedBytes);
			return bSuccess;
		}

		public static bool SendStringToPrinter(string szPrinterName, string szString)
		{
			IntPtr pBytes;
			Int32 dwCount;
			// How many characters are in the string?
			dwCount = szString.Length;
			// Assume that the printer is expecting ANSI text, and then convert
			// the string to ANSI text.
			pBytes = Marshal.StringToCoTaskMemAnsi(szString);
			// Send the converted ANSI string to the printer.
			SendBytesToPrinter(szPrinterName, pBytes, dwCount);
			Marshal.FreeCoTaskMem(pBytes);
			return true;
		}
	}

}

VS içindeki Projeniz şuna benzer bir şekilde görünür…

Artık, nereden isterseniz erişebileceğiniz çok düzgün bir sınıfımız oldu. SendBytesToPrinter içinde, yazdırma yöneticisine gönderilecek döküman adı bilgisini görebilirsiniz. Siz barkod bastır komutu verdiğinizde, Windows yazdırma yöneticinde bu isim görünecektir. Dolayısıyla projenize uygun şık bir isim girebilirsiniz.

Programınızdan kullanımı ise, bir önceki makalede gösterildiği gibidir. Yine de kısaca tekrar etmek gerekirse

RawPrinterHelper.SendStringToPrinter(printerName, barStrings);

şeklindeki bir yapı işinizi görür. Buradaki printerName, windows sürücüleri ile kurulu yazıcınızın adıdır. barstrings ise göndereceğiniz barkod komutlarıdır.

Benzer şekilde, paralel port kullanan nokta vuruşlu yazıcılara da direk USB üzerinden aynı sınıfı kullanarak erişebilirsiniz.

Barkod Printer, Seri Port, USB, C# üzerine… – 3” üzerine 53 düşünce

  1. Merhaba Erdem Bey,

    Bu kod jenerik bir şekilde printer’a data göndermek içindir. Yazdırmak istediğiniz barkodun tasarımını önce yazıcının designer programıyla yapmalısınız. Ondan sonra bu komutları kullanarak tasarladığınız şablon üzerinden printer’dan çıktı alacaksınız.

  2. Merhaba
    Verdiğiniz kod zebra yazıcıda sorunsuz çalıştı. Ben ZPL kodunu dosyadan okumak yerine kendi kod bloğum içerisinde üretip sizin sınıfınızla yazıcıya gönderdim sorunsuz çalıştı.
    Teşekkürler.

  3. Paylaşım için Teşekkürler
    Buda Vb.Net Kodu
    Imports System
    Imports System.Collections.Generic
    Imports System.Text
    Imports System.Runtime.InteropServices
    Imports System.IO

    Namespace VYP
    Public Class RawPrinterHelper

    Public Class DOCINFOA

    Public pDocName As String

    Public pOutputFile As String

    Public pDataType As String
    End Class

    Public Shared Function OpenPrinter(
    ByVal szPrinter As String, ByRef hPrinter As IntPtr, ByVal pd As IntPtr) As Boolean

    Public Shared Function ClosePrinter(ByVal hPrinter As IntPtr) As Boolean

    Public Shared Function StartDocPrinter(ByVal hPrinter As IntPtr, ByVal level As Int32,
    ByVal di As DOCINFOA) As Boolean

    Public Shared Function EndDocPrinter(ByVal hPrinter As IntPtr) As Boolean

    Public Shared Function StartPagePrinter(ByVal hPrinter As IntPtr) As Boolean

    Public Shared Function EndPagePrinter(ByVal hPrinter As IntPtr) As Boolean

    Public Shared Function WritePrinter(ByVal hPrinter As IntPtr, ByVal pBytes As IntPtr, ByVal dwCount As Int32, ByRef dwWritten As Int32) As Boolean

    Public Shared Function SendBytesToPrinter(ByVal szPrinterName As String, ByVal pBytes As IntPtr, ByVal dwCount As Int32) As Boolean
    Dim dwError As Int32 = 0, dwWritten As Int32 = 0
    Dim hPrinter As IntPtr = New IntPtr(0)
    Dim di As DOCINFOA = New DOCINFOA()
    Dim bSuccess As Boolean = False
    di.pDocName = “Mavis RAW Document (Barcode)”
    di.pDataType = “RAW”

    If OpenPrinter(szPrinterName.Normalize(), hPrinter, IntPtr.Zero) Then

    If StartDocPrinter(hPrinter, 1, di) Then

    If StartPagePrinter(hPrinter) Then
    bSuccess = WritePrinter(hPrinter, pBytes, dwCount, dwWritten)
    EndPagePrinter(hPrinter)
    End If

    EndDocPrinter(hPrinter)
    End If

    ClosePrinter(hPrinter)
    End If

    If bSuccess = False Then
    dwError = Marshal.GetLastWin32Error()
    End If

    Return bSuccess
    End Function

    Public Shared Function SendFileToPrinter(ByVal szPrinterName As String, ByVal szFileName As String) As Boolean
    Dim fs As FileStream = New FileStream(szFileName, FileMode.Open)
    Dim br As BinaryReader = New BinaryReader(fs)
    Dim bytes As Byte() = New Byte(fs.Length – 1) {}
    Dim bSuccess As Boolean = False
    Dim pUnmanagedBytes As IntPtr = New IntPtr(0)
    Dim nLength As Integer
    nLength = Convert.ToInt32(fs.Length)
    bytes = br.ReadBytes(nLength)
    pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength)
    Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength)
    bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength)
    Marshal.FreeCoTaskMem(pUnmanagedBytes)
    Return bSuccess
    End Function

    Public Shared Function SendStringToPrinter(ByVal szPrinterName As String, ByVal szString As String) As Boolean
    Dim pBytes As IntPtr
    Dim dwCount As Int32
    dwCount = szString.Length
    pBytes = Marshal.StringToCoTaskMemAnsi(szString)
    SendBytesToPrinter(szPrinterName, pBytes, dwCount)
    Marshal.FreeCoTaskMem(pBytes)
    Return True
    End Function
    End Class
    End Namespace

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir