How to send raw data to a printer by using Visual Basic .NET (322090)
The information in this article applies to:
- Microsoft .NET Framework SDK 1.0
- Microsoft Visual Basic .NET (2002)
- Microsoft Visual Basic .NET (2003)
- Microsoft Windows XP Professional
- the operating system: Microsoft Windows XP 64-Bit Edition
This article was previously published under Q322090
For a Microsoft Visual C# .NET version of this article, see 322091.
For a Microsoft Visual Basic
6.0 version of this article, see 154078.
For an unmanaged C++ version of this article, see 138594. This article refers to the following
Microsoft .NET Framework Class Library namespaces:
- System.IO
- System.Drawing.Printing
- System.Runtime.InteropService
IN THIS TASKSUMMARY This step-by-step article shows you how to use Win32
spooler functions from a program that you create by using Visual Basic .NET.
back to the topMore information To send raw data to a printer from the Microsoft .NET Framework,
your program must work with Win32 spooler functions. Through the .NET
Framework, you can print by using PrintDocument, PrintController, and associated classes. However, with the .NET Framework, you
cannot send preformatted printer-ready data to a printer. You may
have to send raw data to a printer to do the following:
- Send escape sequences.
- Download, and then use soft fonts.
- Spool preprinted files.
To send these types and other types of raw data to a printer,
your code must work with Win32 Spooler Application Programmer Interfaces
(APIs). The following code shows how to read the contents of a preformatted
file into memory, and then send those bytes to the printer by using WritePrinter. NOTE: You cannot use this approach in the same print job as a native PrintDocument print job. You must either use the .NET Framework to print or
send your own print job bytes. back
to the topCreate a project that prints preformatted data To create the project, follow these steps:
- Start Visual Studio .NET. On the File menu, click New, and then click Project. Under Project Types, click the Visual Basic Projects folder. On the Templates list, click Windows Application, and then click OK. By default, Form1 is created.
- On the View menu, click Toolbox to display the Toolbox, and then add a button to Form1. This button is named Button1.
- Add another button to Form1. This button is named Button2.
- Double-click Button1. The code window for the form appears.
- Replace the Button1_Click subroutine with the following code:
' Click event handler for a button - designed to show how to use the
' SendFileToPrinter and SendBytesToPrinter functions.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
' Allow the user to select a file.
Dim ofd As New OpenFileDialog()
If ofd.ShowDialog(Me) Then
' Allow the user to select a printer.
Dim pd As New PrintDialog()
pd.PrinterSettings = New PrinterSettings()
If (pd.ShowDialog() = DialogResult.OK) Then
' Print the file to the printer.
RawPrinterHelper.SendFileToPrinter(pd.PrinterSettings.PrinterName, ofd.FileName)
End If
End If
End Sub ' Button1_Click()
- Replace the Button2_Click subroutine with the following code:
' Click event handler for a button - designed to show how to use the
' SendBytesToPrinter function to send a string to the printer.
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim s As String
Dim pd As New PrintDialog()
' You need a string to send.
s = "Hello, this is a test"
' Open the printer dialog box, and then allow the user to select a printer.
pd.PrinterSettings = New PrinterSettings()
If (pd.ShowDialog() = DialogResult.OK) Then
RawPrinterHelper.SendStringToPrinter(pd.PrinterSettings.PrinterName, s)
End If
End Sub ' Button2_Click()
- Insert the following code at the top of the file:
Imports System.IO
Imports System.Drawing.Printing
Imports System.Runtime.InteropServices
- Add the following code inside the main application
namespace but outside any class definitions:
Public Class RawPrinterHelper
' Structure and API declarions:
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
Structure DOCINFOW
<MarshalAs(UnmanagedType.LPWStr)> Public pDocName As String
<MarshalAs(UnmanagedType.LPWStr)> Public pOutputFile As String
<MarshalAs(UnmanagedType.LPWStr)> Public pDataType As String
End Structure
<DllImport("winspool.Drv", EntryPoint:="OpenPrinterW", _
SetLastError:=True, CharSet:=CharSet.Unicode, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function OpenPrinter(ByVal src As String, ByRef hPrinter As IntPtr, ByVal pd As Long) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="ClosePrinter", _
SetLastError:=True, CharSet:=CharSet.Unicode, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function ClosePrinter(ByVal hPrinter As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="StartDocPrinterW", _
SetLastError:=True, CharSet:=CharSet.Unicode, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function StartDocPrinter(ByVal hPrinter As IntPtr, ByVal level As Int32, ByRef pDI As DOCINFOW) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="EndDocPrinter", _
SetLastError:=True, CharSet:=CharSet.Unicode, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function EndDocPrinter(ByVal hPrinter As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="StartPagePrinter", _
SetLastError:=True, CharSet:=CharSet.Unicode, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function StartPagePrinter(ByVal hPrinter As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="EndPagePrinter", _
SetLastError:=True, CharSet:=CharSet.Unicode, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function EndPagePrinter(ByVal hPrinter As IntPtr) As Boolean
End Function
<DllImport("winspool.Drv", EntryPoint:="WritePrinter", _
SetLastError:=True, CharSet:=CharSet.Unicode, _
ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function WritePrinter(ByVal hPrinter As IntPtr, ByVal pBytes As IntPtr, ByVal dwCount As Int32, ByRef dwWritten As Int32) As Boolean
End Function
' 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 or False on failure.
Public Shared Function SendBytesToPrinter(ByVal szPrinterName As String, ByVal pBytes As IntPtr, ByVal dwCount As Int32) As Boolean
Dim hPrinter As IntPtr ' The printer handle.
Dim dwError As Int32 ' Last error - in case there was trouble.
Dim di As DOCINFOW ' Describes your document (name, port, data type).
Dim dwWritten As Int32 ' The number of bytes written by WritePrinter().
Dim bSuccess As Boolean ' Your success code.
' Set up the DOCINFO structure.
With di
.pDocName = "My Visual Basic .NET RAW Document"
.pDataType = "RAW"
End With
' Assume failure unless you specifically succeed.
bSuccess = False
If OpenPrinter(szPrinterName, hPrinter, 0) Then
If StartDocPrinter(hPrinter, 1, di) Then
If StartPagePrinter(hPrinter) Then
' Write your printer-specific bytes to the printer.
bSuccess = WritePrinter(hPrinter, pBytes, dwCount, dwWritten)
EndPagePrinter(hPrinter)
End If
EndDocPrinter(hPrinter)
End If
ClosePrinter(hPrinter)
End If
' If you did not succeed, GetLastError may give more information
' about why not.
If bSuccess = False Then
dwError = Marshal.GetLastWin32Error()
End If
Return bSuccess
End Function ' SendBytesToPrinter()
' SendFileToPrinter()
' When the function is given a file name and a printer name,
' the function reads the contents of the file and sends the
' contents to the printer.
' Presumes that the file contains printer-ready data.
' Shows how to use the SendBytesToPrinter function.
' Returns True on success or False on failure.
Public Shared Function SendFileToPrinter(ByVal szPrinterName As String, ByVal szFileName As String) As Boolean
' Open the file.
Dim fs As New FileStream(szFileName, FileMode.Open)
' Create a BinaryReader on the file.
Dim br As New BinaryReader(fs)
' Dim an array of bytes large enough to hold the file's contents.
Dim bytes(fs.Length) As Byte
Dim bSuccess As Boolean
' Your unmanaged pointer.
Dim pUnmanagedBytes As IntPtr
' Read the contents of the file into the array.
bytes = br.ReadBytes(fs.Length)
' Allocate some unmanaged memory for those bytes.
pUnmanagedBytes = Marshal.AllocCoTaskMem(fs.Length)
' Copy the managed byte array into the unmanaged array.
Marshal.Copy(bytes, 0, pUnmanagedBytes, fs.Length)
' Send the unmanaged bytes to the printer.
bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, fs.Length)
' Free the unmanaged memory that you allocated earlier.
Marshal.FreeCoTaskMem(pUnmanagedBytes)
Return bSuccess
End Function ' SendFileToPrinter()
' When the function is given a string and a printer name,
' the function sends the string to the printer as raw bytes.
Public Shared Function SendStringToPrinter(ByVal szPrinterName As String, ByVal szString As String)
Dim pBytes As IntPtr
Dim dwCount As Int32
' 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)
End Function
End Class
- Press F5 to build, and then run the program.
- Click Button1 to load and print a file's contents.
- Click Button2 to print a string. (You may have to eject the page manually
because the string is sent without the formfeed command.)
back to the
topREFERENCES
For more information, click the following article number to view the article in the Microsoft Knowledge Base:
138594
How to send raw data to a printer by using the Win32 API
back to the
top
Modification Type: | Minor | Last Reviewed: | 5/4/2006 |
---|
Keywords: | kbDSWGDI2003Swept kbHOWTOmaster KB322090 kbAudDeveloper |
---|
|