2015-04-01 10 views
0

Моя задача - печатать этикетки с помощью термопринтера. С этой целью генерируется и отправляется на принтер последовательность команд tspl (язык программирования, который понимает принтер). Последнее делается в C# с помощью следующего метода, взятого из майкрософт примера "How to send raw data to a printer by using 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 и не имеет общей печати er установлен

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

  1. От PC_aware я подключиться к серверу с помощью ПРР, используя свой публичный адрес IP-
  2. Мой термопринтер появится в «Принтеры и устройства», как «TSC_TDP-244 (перенаправлены 20)»
  3. Я перехожу к свойствам принтера и нажимаю Print Test Page, и он печатается
  4. Запуск моего приложения, и принтер ничего не печатает.

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

+0

Это действительно проблема удаленного рабочего стола. Поскольку PC_unaware не имеет подключения к локальной сети, и общий принтер не установлен на нем, он полагается на функцию клонирования принтера RD, которую я всегда считал проблематичной. Является ли RD действительно важным для проблемы, которую вы пытаетесь решить? Если нет, я бы вытащил его из картинки. –

+0

Эта функция печати должна быть доступна на сервере, и пользователи подключаются к ней через rdp, поэтому я боюсь, что RD является неотъемлемой частью. – zurab

+0

Я не знаю, как RD реализует клонирование принтера, но я сильно подозреваю, что это зависит от задействования спулера, а это значит, что запись непосредственно в клонированные принтеры не будет работать. В RD потребуется много сложного кода для поддержки прямой печати, и это достаточно редко, что я предполагаю, что они не реализовали его. –

ответ

0
PRINTER_DEFAULTS pd; 

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

    if (!OpenPrinter(szPrinterName, &hPrinter, &pd)) 
     return false; 
Смежные вопросы