簡體   English   中英

Microsoft Interop Word Automation的DCOM配置設置

[英]DCOM Config settings for Microsoft Interop Word Automation

我正在使用Microsoft Office Interop Word使用C#生成文檔。 為了使文檔生成正常進行,在Dcom Config Settings下應有一個"Microsoft Office Word 97 - 2003 Document" Dcom Config Settings "Microsoft Office Word 97 - 2003 Document"條目,如下所示:

在此處輸入圖片說明

首次安裝Microsoft Office時,“ General Tab下的“ Local Path ”具有正確的路徑。 如果隨后我將計算機加入域,然后以域用戶的身份重新啟動系統,則Local Path將變為空白,並且應用程序不會生成文檔並顯示錯誤。

即使我先將計算機加入域,然后以域用戶身份登錄然后安裝Microsoft Office, Local Path也將首先正確顯示,然后在重新啟動后再次變為空白。 同時,如果我使用Local User登錄,則Path仍然存在。

是什么導致“ Local Path的值變為空白?

所有這些設置都在虛擬機上執行,而自動化一詞在域帳戶上運行,因為我看到它在加入域的物理機上運行。

UPDATE: What my application is doing:

我的應用程序中有4-5個組件。

第一個是VSTO Word加載項,它與Microsoft Word集成在一起,在其中我們創建了包含一些也保存在數據庫中的表達式的新文檔。 表達式上也有條件,它們也可以嵌套。 表達式包含來自XSD文件的架構元素,這些元素已保存在數據庫中。 創建此類文檔后,其WordML將保存在數據庫中。 所有這些都在VSTO插件中完成。

第二個是Web服務,該服務從另一個組件接收輸入xml,該組件對上面的XSD進行確認,從該組件上方將模式元素嵌入到通過VSTO addIn創建的文檔的表達式中。 該Web服務檢查驗證和其他一些任務。 然后,它從數據庫中獲取相應Word文檔的WordML,並將其傳遞給Word Interop,后者使用其API,以遞歸方式對其進行迭代,以使用輸入xml中的實際值替換架構元素。 然后,這會將WordML保存為Word文檔形式的文件。

這還將在保存模板之前將模板附加到文檔。 它使用Word Interop的SaveAs功能將文件另存為PDF。

更新:我再次瀏覽了完整的應用程序,並了解到我們通過解析Office Open XML來完成所有工作(例如,將輸入提供給word文檔),但是我們使用Word Automation所做的唯一工作就是以下:

  1. 使用Word Interop將生成的WordML保存為Word格式文件之一。
  2. 將生成的WordML導出到PDF文件。
  3. 將多個WordML合並為一個Word文檔文件。
  4. 為此獲取XML。

下面顯示了所有這四個代碼,僅顯示了代碼的相關部分:

Microsoft.Office.Interop.Word.Document wordDocument = null;
object templateName = "templateFile.dotm";
wordDocument = this.WordApplication.Documents.Add(ref missing, ref missing, ref missing, ref missing);
wordDocument.Range(ref missing, ref missing).Text = "";
wordDocument.set_AttachedTemplate(ref templateName);

wordDocument = this.WordApplication.Documents.Open(
                   ref objSourceFilePath, ref oFalse, ref oTrue,
                   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);
wordDocument.ExportAsFixedFormat(
        strTargetPath,
        targetFormat,
        paramOpenAfterExport,
        paramExportOptimizeFor,
        paramExportRange,
        paramStartPage,
        paramEndPage,
        paramExportItem,
        paramIncludeDocProps,
        paramKeepIRM,
        paramCreateBookmarks,
        paramDocStructureTags,
        paramBitmapMissingFonts,
        paramUseISO19005_1,
        ref oMissing);

object SaveToFormat = SaveToFormat = Microsoft.Office.Interop.Word.WdSaveFormat.wdFormatDocument97;
wordDocument.SaveAs(ref objTargetFilePath, ref SaveToFormat, 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);

對於合並多個文件:

Microsoft.Office.Interop.Word.Document doc = null;
Microsoft.Office.Interop.Word.Section section = null;
object sectionBreakNextPage = (object)WdBreakType.wdSectionBreakNextPage;

WordApp.Visible = false;
doc = this.WordApplication.Documents.Add(ref paramMissing, ref paramMissing, ref paramMissing, ref paramMissing);

if (doc != null)
{
    doc.Activate();
    int fileCount = sourceFiles.Length;
    String fileName = string.Empty;

    for (int fileIndex = 0; fileIndex < fileCount; fileIndex++)
    {
        fileName = sourceFiles[fileIndex];
        if (System.IO.File.Exists(fileName))
        {
            section = doc.Sections.Last;
            //delink the current section's header & footer from previous section's header & footer
            section.Headers[WdHeaderFooterIndex.wdHeaderFooterFirstPage].LinkToPrevious = false;
            section.Footers[WdHeaderFooterIndex.wdHeaderFooterFirstPage].LinkToPrevious = false;
            section.Headers[WdHeaderFooterIndex.wdHeaderFooterPrimary].LinkToPrevious = false;
            section.Footers[WdHeaderFooterIndex.wdHeaderFooterPrimary].LinkToPrevious = false;
            section.Headers[WdHeaderFooterIndex.wdHeaderFooterEvenPages].LinkToPrevious = false;
            section.Footers[WdHeaderFooterIndex.wdHeaderFooterEvenPages].LinkToPrevious = false;

            section.Range.InsertFile(fileName, ref paramMissing, ref paramMissing, ref paramMissing, ref paramMissing);
            //if it is last iteration, do'nt insert break
            if (fileIndex < fileCount - 1)
            {
                object rangeStart = (object)(section.Range.End - 1);
                doc.Range(ref rangeStart, ref paramMissing).InsertBreak(ref sectionBreakNextPage);
            }
        }
    }
    doc.SaveAs(ref targetFile, ref wordFormat, ref paramMissing,
        ref paramMissing, ref paramMissing, ref paramMissing,
        ref paramMissing, ref paramMissing, ref paramMissing,
        ref paramMissing, ref paramMissing, ref paramMissing,
        ref paramMissing, ref paramMissing, ref paramMissing,
        ref paramMissing);
    return true;
}

現在,我收到以下錯誤:

The message filter indicated that the application is busy. (Exception from HRESULT: 0x8001010A (RPC_E_SERVERCALL_RETRYLATER))

無需使用Word Automation就可以完成所有這些工作嗎?

我認為您應該閱讀此書 ,然后嘗試另一種解決問題的方法,而不是嘗試修復和處理該錯誤:

(...) Microsoft當前不建議並且不支持從任何無人參與的非交互客戶端應用程序或組件(包括ASP,DCOM和NT Services)自動化Microsoft Office應用程序,因為Office可能表現出不穩定的行為和/或在此環境中運行時死鎖。 (......)

該知識庫中建議的一些替代方法是:

(...) Microsoft強烈推薦許多替代方法,這些替代方法不需要在服務器端安裝Office,並且可以比自動化更有效,更快地執行大多數常見任務。 在將Office作為項目的服務器端組件之前,請考慮其他方法。

大多數服務器端自動化任務涉及文檔創建或編輯。 Office 2007支持新的Open XML文件格式,使開發人員可以在服務器端創建,編輯,讀取和轉換文件內容。 這些文件格式使用Microsoft .NET 3.x Framework中的System.IO.Package.IO命名空間來編輯Office文件,而無需使用Office客戶端應用程序本身。 這是處理服務中Office文件更改的推薦和受支持的方法。 (......)

(...) Microsoft提供了一個SDK,用於處理.NET 3.x Framework中的Open XML文件格式。 有關SDK以及有關如何使用SDK創建或編輯Open XML文件的更多信息,請訪問下面的Microsoft Developer Network(MSDN)網站:

請注意,即使您解決了問題,您的解決方案也將很難穩定……本質上,似乎正在發生的事情是您弄亂了注冊表,似乎您的Word重新安裝並沒有解決您的注冊表問題,並且有問題。

基於此,我建議您閱讀上述文檔,並嘗試使用上述替代方法構建一個更穩定的解決方案,因為您的情況可能會導致來自任何無人值守,非交互客戶端應用程序或組件的Microsoft Office應用程序自動化。表現出不穩定的行為。

更新1

在這里有一個Hello World示例。 使用Open XML創建文檔可以很容易地做到這一點:

public void HelloWorld(string docName) 
{
  // Create a Wordprocessing document. 
  using (WordprocessingDocument package = WordprocessingDocument.Create(docName, WordprocessingDocumentType.Document)) 
  {
    // Add a new main document part. 
    package.AddMainDocumentPart(); 

    // Create the Document DOM. 
    package.MainDocumentPart.Document = 
      new Document( 
        new Body( 
          new Paragraph( 
            new Run( 
              new Text("Hello World!"))))); 

    // Save changes to the main document part. 
    package.MainDocumentPart.Document.Save(); 
  } 
}

注意

我可能會在這里花費數小時來嘗試解決您的注冊表,但是正如您在博客中的這篇文章中所看到的那樣,這些問題令人頭疼,即使您找到解決問題的方法,也不會我認為當然是可維護或可擴展的解決方案。

更新2

根據 ,這些配置諸如本地路徑是從注冊表中提取和不可修改:

(...) “常規”選項卡提供有關應用程序的常規信息。 此選項卡顯示應用程序名稱,類型(本地服務器或遠程服務器)和位置(本地路徑或遠程計算機)。 這些設置無法通過DCOM Config界面進行修改。

“常規”選項卡從以下注冊表項的子項中檢索所有信息:HKEY_CLASSES_ROOT \\ CLSID {... CLSID ...}其中{... CLSID ...}是當前正在查看的對象服務器的唯一CLSID。 (......)

所以! 運行> regedit>轉到HKEY_CLASSES_ROOT \\ CLSID,然后轉到“編輯”菜單,然后單擊“查找”,按鍵過濾並將您的ApplicationID放在此處。 您應該以這種方式找到它。

現在,在找到DCOM的注冊表項之后,將其展開,您應該會看到LocalServer32,該屬性(默認)包含您的Local Path值,嘗試將其更改為與新Oracle Virtual Box中相同的路徑。

如果這行得通,請在每次登錄后測試該值是否重新啟動並使用您的域用戶帳戶登錄后是否保持有效,如果不是,請運行批處理來運行.reg文件以執行此修改。

警告:不過,這是不好的東西,我強烈,強烈建議您采取相反的做法,這不是做到這一點的方法。

更新3

關於“MS-WORD自動化錯誤:‘消息過濾器顯示應用程序正忙’,你有一個很好的回答這個問題在這里 ,我會舉了一下上面的鏈接的,為什么是錯誤的進一步理解發生:

(...)問題是您要調用的Word對象不支持多線程。 由於它們通過COM暴露給任意客戶端,因此存在多個線程嘗試同時在對象中執行代碼的可能性。 為防止這種情況發生,請對所有傳入的電話進行排隊,以使其排隊,並且一次只允許執行一個電話。 這是通過打包每個呼叫的詳細信息並將消息發布到Word來完成的。 當Word處理消息時,調用將在Word自己的主線程上執行。 這種方法的問題在於,如果在呼叫進入時Word忙於做其他事情,則調用者將不得不等待。 (......)

關於合並,該工具聲稱能夠合並OpenXML文檔,但我從未使用過,但是我會嘗試一下(如果您是您)。

(...)用於Open XML的PowerTools包含用於使用Open XML SDK完成各種常見任務的源代碼和指南,例如:-使用HtmlConverter.cs將DOCX高保真地轉換為HTML / CSS; -使用DocumentBuilder.cs合並和拆分DOCX文檔; -使用PresentationBuilder.cs合並和拆分PPTX演示文稿; -使用RevisionAccepter.cs接受DOCX文檔中的跟蹤修訂; -使用TextReplacer.cs搜索和替換DOCX文檔中的文本(...)

最后,要從Word文檔生成PDF,可以在此處使用此工具。

因此,正如您所看到的,您可以繼續處理Word Automation(暗面),或者可以加入Force的輕面:)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM