2016-07-01 85 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