Как отправлять необработанные данные на принтер с помощью Visual C# .NET

Поддержка Windows XP завершена

8 апреля 2014 г. корпорация Майкрософт прекратила поддержку Windows XP. Это повлияло на обновления программного обеспечения и параметры безопасности. Узнайте, что это значит для вас и какие меры по безопасности можно предпринять.

ВНИМАНИЕ! Данная статья переведена с использованием программного обеспечения Майкрософт для машинного перевода и, возможно, отредактирована посредством технологии Community Translation Framework (CTF). Корпорация Майкрософт предлагает вам статьи, обработанные средствами машинного перевода, отредактированные членами сообщества Майкрософт и переведенные профессиональными переводчиками, чтобы вы могли ознакомиться со всеми статьями нашей базы знаний на нескольких языках. Статьи, переведенные с использованием средств машинного перевода и отредактированные сообществом, могут содержать смысловое, синтаксические и (или) грамматические ошибки. Корпорация Майкрософт не несет ответственности за любые неточности, ошибки или ущерб, вызванные неправильным переводом контента или его использованием нашими клиентами. Подробнее об CTF можно узнать по адресу http://support.microsoft.com/gp/machine-translation-corrections/ru.

Эта статья на английском языке: 322091
Эта статья помещена в архив. Она предлагается "как есть" и обновляться не будет.
Для версии Microsoft Visual Basic .NET в данной статье см. 322090.
Для неуправляемой C++ версии данной статьи, обратитесь к следующей статье Microsoft Knowledge Base:
138594 Как отправлять необработанные данные на принтер с помощью интерфейса Win32 API
Данной статье содержатся ссылки на следующие пространства имен библиотеки классов Microsoft платформа.NET Framework:
  • System.IO
  • System.Drawing.Printing
  • System.Runtime.InteropServices

В ЭТОЙ ЗАДАЧЕ

Аннотация
В этой статье показано, как использовать функции Win32 диспетчера очереди печати из программы, созданные с помощью Visual C# .NET.

back to the top

Дополнительные сведения

Чтобы отправить на принтер необработанные данные из Microsoft платформа.NET Framework, программы необходимо работать с очереди функций Win32. Через платформа.NET Framework можно распечатать с помощью PrintDocument, PrintControllerи связанные с ним классы. Тем не менее с платформа.NET Framework, не удается отправить форматированных данных готовые к печати на принтере.

Может потребоваться отправить на принтер следующие исходные данные:
  • Отправьте escape-последовательности.
  • Загрузить и установить шрифты.
  • Файлы очереди готовых бланках.
Чтобы отправить эти типы и других типов исходных данных на принтере, код должен работать с интерфейсов Win32 очереди прикладного программирования (API). Ниже показано, как считывается содержимое предварительно отформатированного файла в память, а затем отправить эти байты на принтер с помощью WritePrinter.

Примечание: этот подход нельзя использовать в же задание на печать как собственные задания печати PrintDocument . Платформа.NET Framework необходимо использовать для печати или отправки байтов собственные задания печати.

back to the top

Создание проекта, вывод форматированных данных

  1. Запустите Visual Studio .NET. В меню Файл выберите команду Создать и выберите Проект. В области Типы проектоввыберите папку Проекты Visual C# . В списке Шаблоны выберите Приложение Windowsи нажмите кнопку ОК. По умолчанию будет создана форма Form1.
  2. В меню Вид выберите команду панели инструментов , чтобы отобразить панель инструментов и добавьте кнопку в форму Form1. Нажмите эту кнопку с именем Button1.
  3. Добавьте кнопку в форму Form1. Нажмите эту кнопку с именем Button2.
  4. Дважды щелкните кнопку Button1. Откроется окно кода для формы.
  5. Замените подпрограмму Button1_Click следующий код:
    private void button1_Click(object sender, System.EventArgs e){    // Allow the user to select a file.    OpenFileDialog ofd = new OpenFileDialog();    if( DialogResult.OK == ofd.ShowDialog(this) )    {        // Allow the user to select a printer.        PrintDialog pd  = new PrintDialog();        pd.PrinterSettings = new PrinterSettings();        if( DialogResult.OK == pd.ShowDialog(this) )        {            // Print the file to the printer.            RawPrinterHelper.SendFileToPrinter(pd.PrinterSettings.PrinterName, ofd.FileName);        }    }}					
  6. Замените подпрограммы Button2_Click следующий код:
    private void button2_Click(object sender, System.EventArgs e){    string s = "Hello"; // device-dependent string, need a FormFeed?        // Allow the user to select a printer.    PrintDialog pd  = new PrintDialog();    pd.PrinterSettings = new PrinterSettings();    if( DialogResult.OK == pd.ShowDialog(this) )    {        // Send a printer-specific to the printer.        RawPrinterHelper.SendStringToPrinter(pd.PrinterSettings.PrinterName, s);    }}					
  7. Вставьте следующий код в верхней части файла:
    using System;using System.Drawing;using System.Drawing.Printing;using System.Windows.Forms;using System.Runtime.InteropServices;					
  8. Добавьте следующий код внутри пространства имен основного приложения, но вне определений классов:
    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.        SendBytesToPrinter(szPrinterName, pBytes, dwCount);        Marshal.FreeCoTaskMem(pBytes);        return true;    }}					
  9. Нажмите клавишу F5 для построения и запустите программу.
  10. Нажмите кнопку Button1 для загрузки и печати содержимого файла.
  11. Нажмите кнопку Button2 , чтобы напечатать строку. (Может потребоваться извлечь страницу вручную, поскольку строка отправляется без команды как прогон страницы .)
back to the top
Ссылки
Для получения дополнительных сведений щелкните следующий номер статьи базы знаний Майкрософт:
138594 Как отправлять необработанные данные на принтер с помощью интерфейса Win32 API
back to the top
НЕОБРАБОТАННЫЕ устройства порта загрузки загружаемых шрифтов

Внимание! Эта статья переведена автоматически

Свойства

Номер статьи: 322091 — последний просмотр: 12/07/2015 10:54:25 — редакция: 5.0

Microsoft Windows XP Professional

  • kbnosurvey kbarchive kbdswgdi2003swept kbhowtomaster kbmt KB322091 KbMtru
Отзывы и предложения