Как печатать в приложениях на базе .NET без графического интерфейса пользователя?

Допустим, у меня есть приложение Windows на основе.NET без графического интерфейса пользователя (например, служба Windows, консольное приложение или веб-служба), и мне нужно что-то напечатать (например, автоматически созданный счет) на физическом принтере.

Какие классы BCL я бы использовал? Вот что я нашел на данный момент:

  • System.Drawing.Printing.PrintDocumentКласс: в документации явно упоминается, что это для печати в приложениях Windows Forms. В частности, упоминается, что приложения WPF должны вместо этого использовать классы из пространства имен System.Printing.
  • System.PrintingПространство имен: в документации прямо упоминается, что эти классы "... не поддерживаются для использования в службе Windows, приложении или службе ASP.NET".

Итак, что следует использовать для печати из приложений без графического интерфейса? (И почему вообще классы печати "привязаны" к UI-фреймворку?)

1 ответ

Он должен нормально работать из консольного приложения. Но да, служба Windows или ASP.NET не так просты.

Есть некоторые предложения здесь, но не так легко из них (например, с помощью P/Invoke использовать C++ библиотеки для печати, которая была моей первой мыслью). Возможно, вы сможете найти людей, которые уже сделали это, если выполните поиск.

Этот ответ рекомендует сторонний продукт: DevExpress'XtraReports.

На Reddit есть еще один парень, который описал, как он решил именно эту задачу. Вы можете отправить ему сообщение на Reddit и посмотреть, сможете ли вы каким-то образом получить его код.

В этом примере используется Microsoft.Office.Interop.Word для печати документов Word из службы Windows. Кажется "хакерским", но я не понимаю, почему это не сработает:

public class WordPrintTask  
{  
 private static object locker = new Object();  
 public WordPrintTask() { }  
 public void PrintWord()  
 {  
   try  
   {  
     // Kill openedword instances.  
     if (KillProcess("WINWORD"))  
     {  
       // Thread safe.  
       lock (locker)  
       {  
         string fileName = "D:\\PrinterDocs\\TEST.docx";  
         string printerName = "\\\\10.0.0.89\\PRINTER1020";  
         if (File.Exists(fileName))  
         {  
           Application _application = new Application();  
           _application.Application.ActivePrinter = printerName;  
           object oSourceFilePath = (object)fileName;  
           object docType = WdDocumentType.wdTypeDocument;  
           object oFalse = (object)false;  
           object oMissing = System.Reflection.Missing.Value;  
           Document _document = _application.Documents.Open(ref oSourceFilePath,  
                              ref docType,  
                              ref oMissing,  
                              ref oMissing,  
                              ref oMissing,  
                              ref oMissing,  
                              ref oMissing,  
                              ref oMissing,  
                              ref oMissing,  
                              ref oMissing,  
                              ref oMissing,  
                              ref oMissing,  
                              ref oMissing,  
                              ref oMissing,  
                              ref oMissing,  
                              ref oMissing);  
           // Print  
           _application.PrintOut(ref oFalse, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,  
                             ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,  
                             ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);  
           object saveOptions = WdSaveOptions.wdDoNotSaveChanges;  
           _document.Close(ref oFalse, ref oMissing, ref oMissing);  
           if (_application != null)  
           {  
             object oSave = false;  
             Object oMiss = System.Reflection.Missing.Value;  
             _application.Quit(ref oSave, ref oMiss, ref oMissing);  
             _application = null;  
           }  
           // Delete the file once it is printed  
           File.Delete(fileName);  
         }  
       }  
     }  
   }  
   catch (Exception ex)  
   {  
     KillProcess("WINWORD");  
   }  
   finally  
   {  
   }  
 }  
 private static bool KillProcess(string name)  
 {  
   foreach (Process clsProcess in Process.GetProcesses().Where(p => p.ProcessName.Contains(name)))  
   {  
     if (Process.GetCurrentProcess().Id == clsProcess.Id)  
       continue;  
     if (clsProcess.ProcessName.Contains(name))  
     {  
       clsProcess.Kill();  
       return true;  
     }  
   }  
   return true;  
 }  
}
Другие вопросы по тегам