【问题标题】:New instance of Word acts as a child process to existing hosted Word applicationWord 的新实例充当现有托管 Word 应用程序的子进程
【发布时间】:2016-03-17 20:32:33
【问题描述】:

我正在开发一个 Word 自动化工具,我在 WPF 窗口中托管 Word。我使用下面的代码来创建一个新的 Word 应用程序

    // Initialize handle value to invalid
    appWin = IntPtr.Zero;

    // Start the remote application
    try
        {
            // Start the process
            if (_wordApp == null) _wordApp = new ApplicationClass();
            _wordApp.Application.Caption = WORD_APP_NAME;

            //find the process
            appWin = FindWindow("Opusapp", _wordApp.Application.Caption);
        }
        catch (Exception ex)
        {
            MessageBox.Show(this, ex.Message, "Error");
        }           

        // Put it into this form
        SetParent(appWin, this.Handle);

在关闭应用程序时,我希望杀死所有生成的 Word 应用程序。

    protected override void OnHandleDestroyed(EventArgs e)
    {
        // Stop the application
        if (appWin != IntPtr.Zero)
        {
            // to be sure that the word app closes without trace 
            try
            {
                uint pid;
                uint pid2 = GetWindowThreadProcessId(appWin,out pid);

                Process proc = Process.GetProcessById((int)pid);
                proc.Kill();
            }
            catch (Exception)
            {
                //write logs.
            }
            _wordApp = null;

            // Clear internal handle
            appWin = IntPtr.Zero;
        }
        base.OnHandleDestroyed (e);
    }

问题是当用户使用这个应用程序并并行打开一个新的 Word 文档时,新的 Word 充当当前进程的子进程,因此在终止进程时,新的 Word 应用程序也会关闭。

如何确保我使用的 Word 应用程序始终与当前运行或稍后打开的任何其他 Word 应用程序不同。

【问题讨论】:

  • 你不需要终止进程。保留对您创建的单词 Application 的引用并调用其 Quit 方法就足够了。
  • 这个问题还是没有好的答案。我想保留一个专用于该软件的后台进程,因为在该框架中以这种方式使用它会更快,但如果我在外部打开另一个 Word,它会打开内部进程。

标签: c# wpf winforms ms-word


【解决方案1】:

您无需终止该进程。保留对您创建的单词Application 的引用然后调用它的Quit 方法就足够了。

例如:

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

Microsoft.Office.Interop.Word.Application word;

private void button1_Click(object sender, EventArgs e)
{
    word = new Microsoft.Office.Interop.Word.Application();
    var documents = word.Documents;
    documents.Open(@"d:\file1.docx");
    SetParent(new IntPtr(word.ActiveWindow.Hwnd), this.Handle);
    word.Visible = true;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    if (word != null)
        word.Quit();
}

【讨论】:

    【解决方案2】:

    您能否不存储您正在生成的 Word 实例的进程 ID,然后在关闭时仅关闭该进程(使用 Process.GetProcesses() 遍历正在运行的进程,将它们与您的进程 ID 匹配存储)

    【讨论】:

    • 我做的完全一样,在上面的代码中我只杀死了我启动的进程,问题是当用户打开一个单词应用程序时(让我们说通过点击桌面上的单词图标)没有创建新进程,相同的进程处理我的托管应用程序和新应用程序。
    • 好的 - 是不是有某种方法可以通过 ApplicationClass 来区分您和用户生成的 Word 实例,即添加新文档时您可以订阅事件吗?
    • ApplicationClass 有一个 Windows 属性,它列出了应用程序中的窗口集合 (msdn.microsoft.com/en-us/library/…) - 你可以遍历它并关闭相应的 Window 对象吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多