2009-02-12 23 views
6

? ¿Cómo imprimir directamente en una impresora de matriz de puntos en C# usando LPT1 archivo.impresión en LPT1 en C#

lo hice en C++ con fopen, pero no sé cómo hacerlo en C#.

muchas gracias

+0

Tengo una respuesta, pero mi nombre no es Michael – geofftnz

+0

Supongo que la copió de un correo electrónico que le envió a alguien que hizo la misma pregunta, simplemente se olvidó de quitarle su nombre. – M4dRefluX

+0

Geeze ... ¿las impresoras matriciales todavía están en uso? Recuerdo haber programado uno alrededor de 1992, pero no había visto uno en años. – abelenky

Respuesta

14

Configurar la impresora en Windows como genérico/sólo texto, y luego imprimir en ella.

Aquí está el código que utilizo para imprimir en una impresora de etiquetas que tiene su propio formato de texto codificado.

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Drawing; 
using System.Drawing.Printing; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 
using System.IO; 

namespace whatever { 

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 = "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); 
      } 
      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. 
     bool success = SendBytesToPrinter(szPrinterName, pBytes, dwCount); 
     Marshal.FreeCoTaskMem(pBytes); 
     return success; 
    } 
} 
} 

Entonces esto se llama de otra clase como esta:

private bool PrintLabels(string printerName) 
    { 
     return RawPrinterHelper.SendStringToPrinter(printerName, this.Text); 
    } 

(edit: si alguien ve alguna fubars importantes relacionados con los recursos no administrados, que me haga saber en los comentarios)

+0

Hombre, Michael es tan increíble. –

+0

¡Gran trabajo, Michael! ¿Qué tal una cita? ; P – strager

+0

brb cambio de nombre a Michael ... – geofftnz

1

Tal vez no puede imprimir en el dispositivo "LPT1" sino en una "impresora de teletipo tonta" que debe instalar primero. Si existen en ventanas modernas ... Por lo tanto, debe imprimir en "mydumbprinter", que a su vez usa LPT1 como puerto de impresora. Me pareció que seguí el enlace Fuente de Cocowalla arriba, allí seleccionas una impresora en un PrinterDialog. El nombre de la impresora resultante sería más probablemente "Laserjet" que "LPT1".

0

En C# es posible, primero debe conectarse a ese puerto utilizando el método CreateFile y luego abrir una secuencia de archivos a ese puerto para finalmente escribir en él. Aquí es una clase de ejemplo que escribe dos líneas a la impresora en LPT1.

using Microsoft.Win32.SafeHandles; 
using System; 
using System.IO; 
using System.Runtime.InteropServices; 

namespace YourNamespace 
{ 
public static class Print2LPT 
     { 
      [DllImport("kernel32.dll", SetLastError = true)] 
      static extern SafeFileHandle CreateFile(string lpFileName, FileAccess dwDesiredAccess,uint dwShareMode, IntPtr lpSecurityAttributes, FileMode dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile); 

      public static bool Print() 
      { 
       string nl = Convert.ToChar(13).ToString() + Convert.ToChar(10).ToString(); 
       bool IsConnected= false; 

       string sampleText ="Hello World!" + nl + 
       "Enjoy Printing...";  
       try 
       { 
        Byte[] buffer = new byte[sampleText.Length]; 
        buffer = System.Text.Encoding.ASCII.GetBytes(sampleText); 

        SafeFileHandle fh = CreateFile("LPT1:", FileAccess.Write, 0, IntPtr.Zero, FileMode.OpenOrCreate, 0, IntPtr.Zero); 
        if (!fh.IsInvalid) 
        { 
         IsConnected= true;      
         FileStream lpt1 = new FileStream(fh,FileAccess.ReadWrite); 
         lpt1.Write(buffer, 0, buffer.Length); 
         lpt1.Close(); 
        } 

       } 
       catch (Exception ex) 
       { 
        string message = ex.Message; 
       } 

       return IsConnected; 
      } 
     } 
} 

Suponiendo que la impresora está conectada en el puerto LPT1, si no tendrá que ajustar el método CreateFile para que coincida con el puerto que está utilizando.

se puede llamar al método de cualquier parte de su programa con la siguiente línea

Print2LPT.Print(); 

Creo que esta es la solución más corto y más eficiente para su problema.