Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 4.0 Office互操作在Windows服务中不起作用_C# 4.0_Windows Services_Vsto_Office Interop - Fatal编程技术网

C# 4.0 Office互操作在Windows服务中不起作用

C# 4.0 Office互操作在Windows服务中不起作用,c#-4.0,windows-services,vsto,office-interop,C# 4.0,Windows Services,Vsto,Office Interop,我对Microsoft Office有一个非常奇怪的问题 我有一个公共库,其唯一目的是打开传递给它的任何word文档文件类型(通过完整文件路径…),并将打开的word文档保存为pdf文件 奇怪的是,如果我从windows服务中使用该库,每当它试图打开word文档时,我都会得到一个空值。。。又名,word文档从未打开过 但是,如果我从WPF或Windows窗体应用程序中使用库,我永远不会有任何问题。我知道线程(单线程装置)存在问题,但我不知道如何修复它以在windows服务中正常工作:(:(:)

我对Microsoft Office有一个非常奇怪的问题

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

奇怪的是,如果我从windows服务中使用该库,每当它试图打开word文档时,我都会得到一个空值。。。又名,word文档从未打开过

但是,如果我从WPF或Windows窗体应用程序中使用库,我永远不会有任何问题。我知道线程(单线程装置)存在问题,但我不知道如何修复它以在windows服务中正常工作:(:(:)

非常感谢您的帮助!我得到的错误如下:

异常消息:{“对象引用未设置为对象的实例。”}(引用word文档)。内部异常:Null;HResult:-2147467261。数据:ListDictionaryInternal,包含0个条目;堆栈跟踪:at DocumentConverter.ToPdf(字符串currentWorkingFolderPath,字符串pathToDocumentToConvert)在c:\Project Files…\DocumentConverter.cs中:第209行

这里是库函数,它需要MicrosoftOffice参考,它是由VisualStudioToolsforOffice创建的

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;
}

您的windows服务是否启用了“在交互模式下运行”选项?它可能会失败,因为Word正在尝试显示UI,但由于一些显而易见的原因,它无法显示UI

另一种可能性(也是人们经常遇到的一个问题)是,您的Windows服务运行的帐户没有访问您试图传递给它的文件/文件夹的权限。相反,WPF/Winforms程序是在用户凭据下运行的

如果这不是问题,是否有任何错误被抛出?请检查Windows事件日志和/或添加一些日志,以查看是否有一些错误被静默抛出


编辑:我浏览了MSDN文档(),似乎不需要使用VSTO。您可以尝试使用纯word interop来执行此操作并查看其是否有效吗?

Office interop在类似服务器的场景中不受MS的支持(如ASP.NET或Windows Service或类似)-请参阅

您需要使用一些库来实现您想要的:

  • (免费)
  • (商业)

    • Per@Sameer在他的帖子中写道:

      Microsoft在Windows server 2008上正式不支持Microsoft Office 2003互操作

      但是在对代码和搜索进行了大量的排列和组合之后,我们发现了一个适合我们场景的解决方案

      解决方案是填补Windows 2003和2008维护其文件夹结构的方式之间的差异,因为Office Interop依赖于桌面文件夹进行文件的中间打开/保存。2003系统将桌面文件夹放在systemprofile下,这在2008年是不存在的

      因此,当我们在2008年在如下所示的相应层次结构下创建此文件夹时,office Interop能够根据需要保存文件

      C:\Windows\System32\config\systemprofile

      C:\Windows\SysWOW64\config\systemprofile


      谢谢大家。!

      我的ASP.net 2.0 office automation应用程序在Windows 2008 Server 64位上运行良好,请按照下面链接中的说明操作。希望对大家有所帮助

      我的示例程序如下所示:

      Imports Microsoft.Office.Interop.Word
      
      
      Dim Result As Boolean = False
      
          Dim appWord As New Microsoft.Office.Interop.Word.Application
          Dim wordDocument As Microsoft.Office.Interop.Word.Document
      
          Try
              Dim oFile As New FileInfo(sPDFFile), sFilePath As String, sFileName As String, sFileNameArr() As String
              Dim sActualFileName As String
      
              sFileName = oFile.Name
              sFileNameArr = sFileName.Split(".")
              sActualFileName = sFileNameArr(0)
              sFilePath = oFile.DirectoryName & "\" & sActualFileName & ".pdf"
      
              wordDocument = appWord.Documents.Open(sPDFFile)
      
              wordDocument.ExportAsFixedFormat(sFilePath, WdExportFormat.wdExportFormatPDF)
              'wordDocument.ExportAsFixedFormat(sFilePath, 17)
      
              Result = True
              oFile = Nothing
      
          Catch ex As COMException
              sErrMsg = ex.InnerException.ToString
              Result = False
          Finally
              wordDocument.Close()
              wordDocument = Nothing
              appWord.Application.Quit()
              appWord = Nothing
      
      
      
          End Try
      
      
          Return Result
      

      创建这些文件夹后:

      C:\Windows\System32\config\systemprofile\Desktop C:\Windows\SysWOW64\config\systemprofile\Desktop


      确保计划任务正在运行,并且配置文件具有访问这些文件夹的权限。

      打开office时没有任何问题。唯一的问题是当word文档作为服务打开时,打开的word文档为空。作为windows窗体,打开的word文档实际上是word文档。该服务在完整的状态下运行dmin帐户。我有日志记录,错误是非常不可描述的。但是,由于office保存的Word文档为空,因此引发了此错误。@bleepzter-“唯一的问题是当Word文档作为服务打开时,打开的Word文档为空”--啊,我确实看到你在代码中设置了
      wordApplication.Visible=false
      。“非描述性”错误消息实际上是怎么说的?你能把它编辑到你的问题中吗?即使它没有帮助,它也会帮助其他人通过搜索引擎找到这个问题。我刚刚添加了异常消息。就像我说的……它确实是非描述性的,但当我附加到服务进程时,它确实会被抛出到WordDocument的SaveAs方法上,因为word文档为空。:(这个问题的答案可以在以下线程中找到:这不是真正的“答案”,但基本上是服务器的安全漏洞:-(从ASP.NET或其他服务器技术使用Office互操作是一个可怕的想法。这些API是为在桌面应用程序中使用而编写的,用于自动化Office(一套桌面应用程序).服务器应用程序在许多方面都不同,因此在其中使用Office Interop是一个非常非常糟糕的主意。Microsoft也不支持它,并且可能会违反您的Office许可证。请参阅我已阅读了Office Server支持手册,这是一个非建设性的声明,显然是:“您(也称我…)完蛋了。”。作为社区的一员,我一直在寻找答案或方向,而不是显而易见的。其他人建议创建一个windows应用程序,并在服务中创建一个新进程,打开windows应用程序进行转换(显然没有UI)这样office运行时才能正确执行。@Sameer S提出了最好的建议,最终证明是解决方案。@bleepzter我提供了解决问题的指导,并提供了一个链接,其中明确指出您所做的不受支持(例如