【问题标题】:Word.Interop document closedWord.Interop 文档已关闭
【发布时间】:2016-07-01 05:51:44
【问题描述】:

我正在尝试将单词拼写检查集成到 WinForms 应用程序中。到目前为止,互操作库一直是一个严重的问题。经过几个小时的折腾,我终于得到了实际的拼写检查工作。 CheckSpellingOnce 以及底层 CheckSpelling 方法按预期执行,但只要我调用 GetSpellingSuggestions,应用程序就会抛出一个...

抛出异常:ClosedCaption.Spelling.dll 中的“System.Runtime.InteropServices.COMException”附加信息:此命令不是 可用,因为没有打开任何文档。

第一个想法是底层 COM 对象与其各自的包装器断开连接,因为 _wordApp 是从与其创建时不同的线程调用的。所以我尝试从 CheckSpelling() 中调用它,不幸的是结果相同。我还尝试打开和关闭文档,将新文档添加到现有应用程序实例,以及从 _document 对象本身 (_document.Application.GetSpellingSuggestions) 获取应用程序。

那是什么?

附加信息:当触发计时器事件时(一旦用户停止在 RichTextField 中输入),就会从 UI 调用 CheckSpellingOnce 方法 - 如此多次 - 使用相同的 _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();
    }

【问题讨论】:

  • 你看过this SO question吗?
  • @JeroenHeier 我有 - 不开心。
  • 错误提示 "no document is open" 所以怀疑这是线程问题。此外,COM 线程模型在这里不适用,因为我们要处理多个进程。
  • 您是否需要按照 Jeroen 的链接为 MainDictionary 提供值?
  • @MickyD 但是我试过打开一个新文档,打开同一个文档作为第二个实例,添加另一个文档并使用那个,等等。

标签: c# .net ms-word office-interop comexception


【解决方案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。

如果有人需要,可以提供更多代码。

感谢您的建议,干杯!

【讨论】:

  • 谁会猜到。很高兴你成功了:)
猜你喜欢
  • 2018-07-06
  • 1970-01-01
  • 1970-01-01
  • 2018-08-05
  • 2012-10-07
  • 2018-02-20
  • 2022-11-28
  • 2010-10-31
  • 2011-02-08
相关资源
最近更新 更多