【发布时间】:2012-11-20 17:55:05
【问题描述】:
我对 Microsoft Office 有一个非常奇怪的问题。
我有一个公共库,其唯一目的是打开任何传递给它的 word 文档文件类型(通过完整的文件路径...)并将打开的 word 文档另存为 pdf 文件。
奇怪的问题是,如果我从 Windows 服务中使用该库,每当它尝试打开 word 文档时,我都会得到一个空值……也就是说,word 文档永远不会被打开。
但是,如果我使用 WPF 或 Windows 窗体应用程序中的库,我就不会遇到任何问题。我知道线程存在问题,(单线程公寓)但是我不知道如何修复它以摆脱 Windows 服务。 :( :( :(
如果有任何帮助,我将不胜感激!我得到的错误如下:
异常消息:{“对象引用未设置为对象的实例。”}(指的是 word 文档)。内部异常:空; H结果:-2147467261。数据:ListDictionaryInternal,有 0 个条目;堆栈跟踪:在 c:\Project Files...\DocumentConverter.cs:line 209 中的 DocumentConverter.ToPdf(String currentWorkingFolderPath, String pathToDocumentToConvert) 处
所以这里是库函数。它需要由 Visual Studio Tools for Office 创建的 Microsoft Office 参考。
private string ToPDF(string currentWorkingFolderPath, string pathToDocumentToConvert)
{
string temporaryPdfFolderPath = Path.GetFullPath(currentWorkingFolderPath + "\\pdf\\");
string temporaryPdfFilePath = Path.GetFullPath(temporaryPdfFolderPath + "\\pdffile.pdf");
if (!FileSystem.CreateDirectory(temporaryPdfFolderPath))
{
return null;
}
try
{
Microsoft.Office.Interop.Word.Application wordApplication = new Microsoft.Office.Interop.Word.Application();
object objectMissing = System.Reflection.Missing.Value;
wordApplication.Visible = false;
wordApplication.ScreenUpdating = false;
FileInfo wordFile = new FileInfo(pathToDocumentToConvert);
Object fileName = (Object)wordFile.FullName;
// This is where it breaks when called from windows service. Use the dummy value as a placeholder for optional arguments
Document wordDocument = wordApplication.Documents.Open(ref fileName, ref objectMissing,
true, ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing,
ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing,
ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing);
object outputFileName = (object)temporaryPdfFilePath;
object fileFormat = WdSaveFormat.wdFormatPDF ;
// Save document into PDF Format
wordDocument.SaveAs(ref outputFileName,
ref fileFormat, ref objectMissing, ref objectMissing,
ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing,
ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing,
ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing);
// Close the Word document, but leave the Word application open.
// doc has to be cast to type _Document so that it will find the
// correct Close method.
object saveChanges = WdSaveOptions.wdDoNotSaveChanges;
((_Document)wordDocument).Close(ref saveChanges, ref objectMissing, ref objectMissing);
wordDocument = null;
// word has to be cast to type _Application so that it will find
// the correct Quit method.
((Microsoft.Office.Interop.Word._Application)wordApplication).Quit(ref objectMissing, ref objectMissing, ref objectMissing);
wordApplication = null;
}
catch (Exception ex)
{
//logging code
return null;
}
return temporaryPdfFilePath;
}
【问题讨论】:
-
这个问题的答案可以在以下线程中找到:stackoverflow.com/questions/4438121/…
-
这不是真正的“答案”,但基本上是您服务器的安全漏洞:-(
-
从 ASP.NET 或其他服务器技术使用 Office 互操作是一个可怕的想法。这些 API 是为在桌面应用程序中使用而编写的,用于自动化 Office(一套桌面应用程序)。服务器应用程序在许多方面都不同,这使得在其中使用 Office Interop 是一个非常非常糟糕的主意。它也不受 Microsoft 支持,并且可能违反您的 Office 许可证。见Considerations for server-side Automation of Office
标签: c#-4.0 windows-services vsto office-interop