它应该可以在控制台应用程序中正常工作。但是,是的,Windows 服务或 ASP.NET 并不那么容易。
有一些建议here,但并不容易(比如使用 P/Invoke 使用 C++ 库进行打印,这是我的第一个想法)。如果您搜索,您也许可以找到已经这样做的人。
This answer 推荐第三方产品:DevExpress' XtraReports。
Reddit 上还有 this guy 描述了他是如何解决这个问题的。你可以在 Reddit 上send him a message 看看你能不能得到他的代码。
This example 使用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;
}
}