c# - 如何在基于 .NET 的非 GUI 应用程序中打印?
问题描述
假设我有一个没有 GUI 的基于 .NET 的 Windows 应用程序(例如,Windows 服务、控制台应用程序或 Web 服务),我需要在物理打印机上打印一些东西(例如,自动创建的发票)。
我将使用 BCL 的哪些类别?这是我到目前为止发现的:
System.Drawing.Printing.PrintDocument
类:文档明确提到这是用于在Windows 窗体应用程序中打印的。特别是,它提到 WPF 应用程序应该使用 System.Printing 命名空间中的类。System.Printing
命名空间:文档明确提到这些类“ ......不支持在 Windows 服务或 ASP.NET 应用程序或服务中使用。 ”
那么,我应该使用什么来从非 GUI 应用程序打印?(以及为什么打印类无论如何都“绑定”到 UI 框架?)
解决方案
它应该可以从控制台应用程序正常工作。但是,是的,Windows 服务或 ASP.NET 并不那么容易。
这里有一些建议,但并不容易(比如使用 P/Invoke 使用 C++ 库进行打印,这是我的第一个想法)。如果您搜索,您可能会找到已经这样做的人。
此答案推荐第三方产品:DevExpress' XtraReports。
Reddit 上还有一个人描述了他是如何解决这个问题的。你可以在 Reddit 上给他发消息,看看你能不能得到他的代码。
此示例用于Microsoft.Office.Interop.Word
从 Windows 服务打印 Word 文档。似乎“hacky”,但我不明白为什么它不起作用:
public class WordPrintTask
{
private static object locker = new Object();
public WordPrintTask() { }
public void PrintWord()
{
try
{
// Kill opened word 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;
}
}
推荐阅读
- r - 如何自动让一些代码运行我打开 RStudio 的所有内容?
- c++ - 如何转发将枚举类声明为模板类的内部类?
- r - 如何将列表元素传递给R中的模型?
- sql - SQL:不支持选择 * - 从子查询中获取列名
- java - webflux如何将当前登录单声道字符串传递给通量
- javascript - 在 React Js 中动态渲染数组元素
- javascript - 在 Angular 8 中上传 CSV 或 Excel 文件,并在网格中显示文件的数据(列和行)作为 Angular 8 中的预览 - 无需外部库
- c# - Entity Framework Core v3:消除重复数据
- java - 由于超出配额,出现 403 错误。但是没有超过配额?
- javascript - 组件没有完全渲染并且没有随着状态的变化而变化