Office Interop在Windows服务中不起作用 [英] Office Interop Does Not Work in Windows Service

查看:326
本文介绍了Office Interop在Windows服务中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常古怪的问题与Microsoft Office。



我有一个公共库,其唯一的目的是打开任何文档文件类型传递给它(通过一个完整的文件路径...),并保存该开放字文档作为pdf文件。



奇怪的问题是,如果我从一个Windows服务消耗该库,每当它试图打开word文档,我得到一个null。 .. aka,文字从来没有打开过。



然而,如果我从一个WPF或Windows窗体应用程序使用库,我从来没有任何问题。我知道有线程的问题,(单线程公寓),但我不知道如何解决它工作的Windows服务。错误我得到的是以下:



异常消息:{对象引用未设置为对象的实例}(引用字文档)内部异常:Null; HResult:-2147467261数据:ListDictionaryInternal,带0个条目;堆栈跟踪:在DocumentConverter.ToPdf因此,这里是库函数,它需要()函数,这个函数需要一个函数,这个函数需要一个函数,

 私人字符串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);

对象fileName =(Object)wordFile.FullName;

//这是从Windows服务调用时打断的位置。使用虚拟值作为可选参数的占位符
文档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);



对象outputFileName =(object)temporaryPdfFilePath;
object fileFormat = WdSaveFormat.wdFormatPDF;

//将文档保存为PDF格式
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);

//关闭Word文档,但保持Word应用程序打开。
// doc必须转换为类型_Document,以便它将找到
//正确的Close方法。
object saveChanges = WdSaveOptions.wdDoNotSaveChanges;
((_Document)wordDocument).Close(ref saveChanges,ref objectMissing,ref objectMissing);

wordDocument = null;

//字必须转换为类型_Application,以便它将找到
//正确的Quit方法。
((Microsoft.Office.Interop.Word._Application)wordApplication).Quit(ref objectMissing,ref objectMissing,ref objectMissing);

wordApplication = null;

}
catch(Exception ex)
{
//日志代码
return null;
}

return temporaryPdfFilePath;
}


解决方案

Per @Sameer S post: Windows Server 2008上是否支持Office 2003 interop?



正式的Microsoft Office 2003 Interop不受Microsoft的Windows Server 2008支持。



但是经过很多排列和与代码和搜索的组合,我们遇到了一个适用于我们的场景的解决方案。



解决方案是插入Windows 2003和2008维护其文件夹之间的区别结构,因为Office Interop依赖于桌面文件夹中的文件打开/保存中间。



因此,当我们在2008年在相应的层次下创建此文件夹时,如下所示:办公室Interop可以根据需要保存文件。此桌面文件夹需要在

下创建

C:\Windows \System32\config\systemprofile



AND



C:\Windows\SysWOW64\config\systemprofile



..!


I have a very weird issue with Microsoft Office.

I have a common library whose sole purpose is to open whatever word document file type is passed to it (by a full file path...) and save that opened word document as a pdf file.

The weird issue is that if I consume that library from a windows service, whenever it attempts to open the word document, I get a null... aka, the word document never got opened.

If however I consume the library from a WPF or Windows Form application I never have any issues. I am aware that there are issues with threading, (Single Thread Appartment) however I have no idea how to fix it to work out of the windows service. :( :( :(

I would appreciate any help! The Error I get Is the following:

Exception Message: {"Object reference not set to an instance of an object."} (Referring to the word document). Inner Exception: Null; HResult: -2147467261. Data: ListDictionaryInternal with 0 entries; Stack Trace: at DocumentConverter.ToPdf(String currentWorkingFolderPath, String pathToDocumentToConvert) in c:\Project Files...\DocumentConverter.cs:line 209

So here is the library function. It requires the Microsoft Office reference, which is created by the Visual Studio Tools for 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;
}

解决方案

Per @Sameer S in his post: Is Office 2003 interop supported on Windows server 2008 ..?

Officially Microsoft Office 2003 Interop is not supported on Windows server 2008 by Microsoft.

But after a lot of permutations & combinations with the code and search, we came across one solution which works for our scenario.

The solution is to plug the difference between the way Windows 2003 and 2008 maintains its folder structure, because Office Interop depends on the desktop folder for file open/save intermediately. The 2003 system houses the desktop folder under systemprofile which is absent in 2008.

So when we create this folder on 2008 under the respective hierarchy as indicated below; the office Interop is able to save the file as required. This Desktop folder is required to be created under

C:\Windows\System32\config\systemprofile

AND

C:\Windows\SysWOW64\config\systemprofile

Thanks Guys..!

这篇关于Office Interop在Windows服务中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆