2016-07-01 83 views
0

我正在嘗試將Word拼寫檢查整合到WinForms應用程序中。到目前爲止,互操作庫已經成爲後方劇烈的痛苦。經過幾個小時的搞亂之後,我終於得到了實際的拼寫檢查工作。該CheckSpellingOnce以及底層CheckSpelling方法達到預期效果,但只要我打電話GetSpellingSuggestions,應用程序將引發...Word.Interop文檔關閉

拋出異常:「System.Runtime.InteropServices.COMException」在ClosedCaption。 Spelling.dll其他信息:此命令不是 可用,因爲沒有文檔處於打開狀態。

第一個想法是,底層COM對象與其各自的包裝器斷開連接,因爲_wordApp是從與創建它不同的線程調用的。所以我嘗試從CheckSpelling()中調用它,不幸的是結果相同。我也嘗試打開和關閉文檔,向現有應用程序實例添加一個新文檔,以及從_document對象本身獲取應用程序(_document.Application.GetSpellingSuggestions)。

那麼給了什麼?

附加信息:CheckSpellingOnce方法在定時器事件被觸發時(一旦用戶停止在RichTextField中輸入時)被多次調用 - 使用相同的_wordApp對象,因爲我試圖避免啓動winword.exe的多個實例。

/// <summary> 
    /// Checks spelling with the text from the provided richtextbox in a new thread. 
    /// </summary> 
    public void CheckSpellingOnce() 
    { 
     _checkerThread = new Thread(new ThreadStart(CheckSpelling)); 
     _checkerThread.Start(); 
    } 

    /// <summary> 
    /// Checks the spelling of a richtextbox. Raises an event with the result when done. 
    /// </summary> 
    private void CheckSpelling() 
    { 
     if (_shouldBeChecking) 
     { 
      RaiseStatusChanged(SpellCheckStatus.Working); 
      Word.ProofreadingErrors toReturn = null; 
      UpdateStringFromTextBox(); 

      if (!string.IsNullOrEmpty(_fromTextBox)) 
      { 
       _document.Content.Delete(); 
       _document.Words.First.InsertBefore(_fromTextBox); 

       _document.Content.LanguageID = _language; //Must be set specifically here for some f***d reason. 

       toReturn = _document.SpellingErrors; 

       RaiseSpellingChecked(toReturn); 
       RaiseStatusChanged(SpellCheckStatus.Idle); 
      } 
     } 
    } 

    public Word.SpellingSuggestions GetSpellingSuggestions(string word) 
    { 
     //throw new NotImplementedException(); 
     Word.SpellingSuggestions toReturn = _wordApp.GetSpellingSuggestions(word, _missing, _missing, _missing, _missing, _missing, _missing); 
     return toReturn; 
    } 

即使有這樣的實施GetSpellingSuggestions的,它抱怨在「toReturn」行,而不是在它上面的那些...

 public void GetSpellingSuggestions(string word) 
    { 
     //throw new NotImplementedException(); 
     var _suggestionThread = new Thread(new ThreadStart(() => 
     { 
      _document.Content.Delete(); 
      _document.Words.First.InsertBefore(word); 

      _document.Content.LanguageID = _language; 
      Word.SpellingSuggestions toReturn = _wordApp.GetSpellingSuggestions(word, _missing, _missing, _missing, _missing, _missing, _missing); 
      Debug.Print(toReturn[0].ToString()); 
     })); 
     _suggestionThread.Start(); 
    } 
+0

你有沒有看過[this](http://stackoverflow.com/questions/9718687/spell-checking-in-c-sharp-using-word-interop)SO問題? –

+0

@JeroenHeier我有 - 沒有快樂。 –

+0

錯誤顯示_「沒有文檔打開」_因此它是一個線程問題值得懷疑。另外,COM線程模型在這裏不適用,因爲我們正在處理多個進程。 – MickyD

回答

1
 /// <summary> 
     /// Opens a Word interop lib document. 
     /// </summary> 
     /// <returns></returns> 
     private Word._Document OpenDocument() 
     { 
      object visible = false; 

      _document = _wordApp.Documents.Add(_missing, _missing, _missing, visible); 
      return _document; 
     } 

這是我怎麼打開我的文檔(在記憶中)。

將visible參數設置爲'true'可以解決問題 - 但由於某種原因(如我的情況那樣)使應用程序進程在後臺運行。 我的理論是,winword.exe保持不可見狀態,直到調用像Document.CheckSpelling()這樣的方法 - 實際上調用Word GUI。

如果有人需要它可以提供更多的代碼。

感謝您的建議,乾杯!

+0

誰會猜到。很高興你得到它:) – MickyD