Печать этикеток через перенаправленный принтер

Моя задача - печатать этикетки через термопринтер. Для этого генерируется строка команд tspl(язык программирования, который понимает принтер) и отправляется на принтер. Последнее сделано в C# с помощью следующего метода, взятого из примера Microsoft "Как отправить необработанные данные на принтер с помощью Visual C# .NET"

        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();
            MessageBox.Show("Error " + dwError);
        }
        return bSuccess;
    }

Фактический принтер выбран в PrintDialog

        private void button2_Click(object sender, EventArgs e)
    {
        string s = "CLS\nPRINT 1\n"; // 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);
        }
    }

В моей рабочей среде все работает отлично. Среда представляет собой локальную сеть, состоящую из 3 компьютеров и 1 общего термопринтера:

  1. PC_with_printer - работает в Windows 7 и к нему подключен принтер через USB
  2. PC_aware - работает на Win 8 и знает об общем принтере
  3. PC_unaware - он работает на WinXP и на нем не установлен общий принтер

С PC_aware я подключаюсь к PC_unaware через rdp, и принтер появляется в списке принтеров как перенаправленный. Затем я запускаю свое приложение, выбираю перенаправленный принтер и печатаю мою пустую этикетку. Все идет нормально.
Проблемы начинаются, когда я заменяю PC_unaware другим компьютером. Он работает на Windows Server 2008 R2 и не находится в нашей локальной сети. Давайте назовем это SERVER. Поэтому я провожу тот же эксперимент:

  1. С PC_aware я подключаюсь к серверу через RDP, используя его публичный IP-адрес
  2. Мой термопринтер отображается в "Принтеры и устройства" как "TSC_TDP-244 (перенаправлено 20)"
  3. Я захожу в свойства принтера и нажимаю "Печать тестовой страницы", и она распечатывается
  4. Я запускаю свое приложение, и принтер ничего не печатает.

Я проверил возвращаемые значения всех функций winapi, которые используются в методе SendBytesToPrinter (OpenPrinter,StartDocPrinter, StartPagePrinter, WritePrinter,EndPagePrinter,EndDocPrinter, ClosePrinter), и ни одна из них не указывает на ошибку. Есть идеи, почему это происходит и как это можно исправить?

1 ответ

PRINTER_DEFAULTS pd;

    pd.DesiredAccess = PRINTER_ACCESS_USE;
    pd.pDatatype = NULL;
    pd.pDevMode = NULL;

    if (!OpenPrinter(szPrinterName, &hPrinter, &pd))
        return false;
Другие вопросы по тегам