Estás trabajando sin conexión, espera a que vuelva la conexión a Internet

Cómo usar Visual Basic .NET para enviar datos sin formato a una impresora

Ha finalizado el soporte técnico para Windows XP

Microsoft puso fin al soporte técnico para Windows XP el 8 de abril de 2014. Este cambio ha afectado a las actualizaciones de software y las opciones de seguridad. Sepa qué significa esto en su caso y cómo puede mantenerse protegido.

Para obtener una versión de este artículo para Microsoft Visual C# .NET, vea 322091.
Para obtener una versión de este artículo para Microsoft Visual Basic 6.0, vea 154078.
Para obtener una versión de C++ no administrado de este artículo, consulte 138594.

Este artículo hace referencia a los siguientes espacios de nombres de la Biblioteca de clases de Microsoft .NET Framework:
  • System.IO
  • System.Drawing.Printing
  • System.Runtime.InteropService

EN ESTA TAREA

Resumen
En este artículo paso a paso se muestra cómo usar las funciones de cola de impresión Win32 en un programa creado mediante Visual Basic .NET.

Más información

Para enviar a una impresora datos sin formato desde Microsoft .NET Framework, el programa debe poder usarse con las funciones de cola de impresión Win32. Mediante .NET Framework, puede imprimir con PrintDocument, PrintController y las clases asociadas. Sin embargo, con .NET Framework no puede enviar a una impresora datos con formato previo preparados para imprimir.

Puede que tenga que enviar los datos sin formato para hacer lo siguiente:
  • Enviar secuencias de escape.
  • Descargar y usar fuentes transferibles.
  • Enviar a la cola de impresión archivos preimpresos.
Para enviar a una impresora éstos y otros tipos de datos sin formato, el código debe poder usarse con las Interfaces de programación de aplicaciones (API) de cola de impresión Win32. En el código siguiente se muestra cómo leer en memoria el contenido de un archivo con formato previo y enviar después esos bytes a la impresora mediante WritePrinter.

NOTA
No puede usar esta solución en el mismo trabajo de impresión que un trabajo de impresión PrintDocument original. Debe usar .NET Framework para imprimir o enviar los bytes del trabajo de impresión.


Crear un proyecto que imprime datos con formato previo

Para crear el proyecto, siga estos pasos:
  1. Inicie Visual Studio .NET. En el menú Archivo, haga clic en Nuevo y, después, haga clic en Proyecto. En Tipos de proyecto, haga clic en la carpeta Proyectos de Visual Basic. En la lista Plantillas, haga clic en Aplicación para Windows y, a continuación, haga clic en Aceptar. De forma predeterminada, se crea Form1.
  2. En el menú Ver, haga clic en Cuadro de herramientas para mostrar el cuadro de herramientas y agregue un botón a Form1. Este botón se denomina Button1.
  3. Agregue otro botón a Form1. Este botón se denomina Button2.
  4. Haga doble clic en Button1. Aparecerá la ventana de código del formulario.
  5. Reemplace la subrutina Button1_Click con el código siguiente:
        ' 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()					
  6. Reemplace la subrutina Button2_Click con el código siguiente:
        ' 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()					
  7. Inserte el código siguiente al principio del archivo:
    Imports System.IOImports System.Drawing.PrintingImports System.Runtime.InteropServices					
  8. Agregue el código siguiente dentro del espacio de nombres de la aplicación principal pero fuera de las definiciones de clase:
    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 FunctionEnd Class					
  9. Presione F5 para generar el programa y a continuación ejecútelo.
  10. Haga clic en Button1 para cargar e imprimir el contenido de un archivo.
  11. Haga clic en Button2 para imprimir una cadena. (Puede que tenga que quitar la página manualmente ya que la cadena se envía sin el comando formfeed.)
Referencias
Para obtener más información al respecto, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
138594 Cómo enviar a una impresora datos sin formato utilizando la API Win32
Propiedades

Id. de artículo: 322090 - Última revisión: 09/25/2006 16:28:00 - Revisión: 7.1

  • Microsoft .NET Framework Software Development Kit 1.0 Service Pack 2
  • Microsoft Visual Basic .NET 2002 Standard Edition
  • Microsoft Visual Basic .NET 2003 Standard Edition
  • Microsoft Windows XP Professional
  • the operating system: Microsoft Windows XP 64-Bit Edition
  • kbhowtomaster kbdswgdi2003swept KB322090
Comentarios