如何使用 Visual C# 自动执行正在运行的 Office 程序实例

摘要

本分步文章介绍如何创建 Microsoft Visual C# 2005 或 Microsoft Visual C# .NET 客户端,该客户端获取对运行中的 Office 程序实例的自动化引用。

创建 Visual C# 2005 或 Visual C# .NET 应用程序,用于自动执行 Office 程序的运行实例

自动执行 Office 的客户端程序可以创建该 Office 程序的新实例,也可以获取对已运行的实例的引用。 Microsoft 通常建议创建新实例,而不是附加到正在运行的实例。 但是,在某些情况下,客户端程序必须自动执行已在运行的 Office 程序实例。 在这种情况下,自动化客户端从运行对象表 (ROT) 获取对自动化服务器的组件对象模型 (COM) 对象的引用。

如果自动化服务器在“正在运行的对象表”中注册,则 .NET 客户端可以通过调用以下命令获取对正在运行实例的引用:

System.Runtime.InteropServices.Marshal.GetActiveObject

- 或者 -

System.Runtime.InteropServices.Marshal.BindToMoniker

示例代码

  1. 启动 Microsoft Visual Studio 2005 或 Microsoft Visual Studio .NET。 在“文件”菜单上,单击“新建”,然后单击“项目”。 在“项目类型”下,单击“Visual C# 项目”,然后在“模板”下单击“Windows 应用程序”。 默认情况下会创建 Form1。

    注意 在 Visual C# 2005 中,单击 Visual C# 而不是 Visual C# 项目

  2. 添加对 Microsoft Excel 对象库和 Microsoft Word 对象库的引用。 为此,请按照下列步骤操作:

    1. 在"项目"菜单上单击"添加引用"。

    2. 在“COM”选项卡上,找到Microsoft Excel 对象库,然后单击“选择”。

      注意 在 Visual C# 2005 中,无需单击“ 选择”。

      注意 Microsoft Office 2003 包括主要互操作程序集 (PIA) 。 Microsoft Office XP 不包括 PIA,但可能会下载它们。

    3. 找到 Microsoft Word 对象库,然后单击“选择”。

      注意 在 Visual C# 2005 中,无需单击“ 选择”。

    4. 在“添加引用”对话框中,单击“确定”以接受所选内容。

  3. 在“视图”菜单上,单击“工具箱”以显示工具箱。 向 Form1 添加三个按钮和一个文本框。 键入这些控件的文本,如下所示:

    ID Text
    button1 获取对运行 Excel 实例的自动化引用
    button2 使用文件名字对象获取 Excel 的自动化引用
    button3 Shell Word 和获取对它的自动化引用
    textBox1 输入已保存的 xls 文件的文件名
  4. 设置按钮控件的 Click 事件处理程序,如下所示:

    1. 双击按钮 1,然后单击“视图”菜单上的“设计器”。
    2. 双击 button2,然后单击“视图”菜单上的“设计器”。
    3. 双击按钮 3。
  5. 在其他 using 语句之后,将以下代码添加到 Form1.cs 的顶部:

    using Excel = Microsoft.Office.Interop.Excel;
    using Word = Microsoft.Office.Interop.Word;
    
  6. 将以下代码添加到事件处理程序:

    private void button1_Click(object sender, System.EventArgs e)
    {
    
    //Excel Application Object
    Excel.Application oExcelApp;
    
    this.Activate();
    
    //Get reference to Excel.Application from the ROT.
    oExcelApp =  (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
    
    //Display the name of the object.
    MessageBox.Show(oExcelApp.ActiveWorkbook.Name);
    
    //Release the reference.
    oExcelApp = null;
    }
    
    private void button2_Click(object sender, System.EventArgs e)
    {
    Excel.Workbook  xlwkbook;
    Excel.Worksheet xlsheet;
    
    //Get a reference to the Workbook object by using a file moniker.
    //The xls was saved earlier with this file name.
    xlwkbook = (Excel.Workbook)  System.Runtime.InteropServices.Marshal.BindToMoniker(textBox1.Text); 
    
    string sFile = textBox1.Text.Substring(textBox1.Text.LastIndexOf("\\")+1);
    xlwkbook.Application.Windows[sFile].Visible = true;
    xlwkbook.Application.Visible = true;
    xlsheet = (Excel.Worksheet) xlwkbook.ActiveSheet;
    xlsheet.Visible = Excel.XlSheetVisibility.xlSheetVisible;
    xlsheet.Cells[1,1] = 100;
    
    //Release the reference.
    xlwkbook = null;
    xlsheet = null;
    }
    
    private void button3_Click(object sender, System.EventArgs e)
    {
    Word.Application wdapp;
    
    //Shell Word
    System.Diagnostics.Process.Start("<Path to WINWORD.EXE>");
    
    this.Activate();
    
    //Word and other Office applications register themselves in 
    //ROT when their top-level window loses focus. Having a MessageBox 
    //forces Word to lose focus and then register itself in the ROT.
    
    MessageBox.Show("Launched Word");
    
    //Get the reference to Word.Application from the ROT.
    wdapp = (Word.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Word.Application");
    
    //Display the name.
    MessageBox.Show(wdapp.Name);
    
    //Release the reference.
    wdapp = null;
    }
    
    

    注意 在 button3_click () 中,将 Winword.exe路径 替换为Winword.exe的正确路径。 Microsoft Word 的默认位置是 C:\Program Files\Microsoft Office\Office\Winword.exe。

  7. 在“生成”菜单上,选择“生成解决方案”以生成应用程序。

测试应用程序

  1. 按 F5 生成并运行应用程序。
  2. 关闭 Excel 的所有正在运行的实例。
  3. 使用新工作簿启动 Excel。
  4. 单击 “获取自动化引用”以运行 Excel 实例 按钮。
  5. 应用程序获取对 Excel 现有实例的自动化引用。 自动化引用存储在用于button1_Click的本地变量 oExcelApp 中。 消息框显示活动工作簿的名称。
  6. 将工作簿保存到本地磁盘。 使工作簿在 Excel 中保持打开状态。
  7. 在 textBox1 中键入在上一步中保存的工作簿的完整路径和文件名。
  8. 使用“文件名字对象”按钮单击“获取 Excel 自动化引用”。
  9. 应用程序获取对运行中的 Excel 实例的自动化引用。 自动化引用存储在本地变量 xlwkbookfor button2_Click中。 活动工作表的第一行和第一列中输入的值为 100。
  10. 退出 Excel 而不保存对工作簿的更改。
  11. 使用“文件名字对象”按钮单击“获取 Excel 自动化引用”。
  12. 将创建 Excel 的新实例,并打开以前保存的工作簿。 应用程序获取对此 Excel 实例的自动化引用。 自动化引用存储在用于button2_Click的本地变量 xlwkbook 中。 活动工作表的第一行和第一列中输入的值为 100。
  13. 关闭 Excel。
  14. 单击 Shell Word 并获取对它的自动化引用 按钮。
  15. Word 启动,就像从命令提示符启动一样,并显示“启动的 Word”消息框。 显示消息框会强制将WM_SETFOCUS消息发送到 Word 程序窗口。 这允许 Word 在运行对象表 (ROT) 中注册自身。
  16. 关闭消息框。 该程序获取对新启动的 Word 实例的自动化引用。 自动化引用存储在用于button3_Click的本地变量 wdapp 中。 将显示一个消息框,显示 Word.Application 对象的名称。

其他注意事项

COM 服务器可以归类为多用 (单个实例) 或单一使用 (多个实例) ,具体取决于可在单台计算机上同时运行的服务器的实例数。

当对新 COM 对象的请求 (单个实例) COM 服务器时,服务器仅使用.exe文件的一个实例来创建该对象。 无论有多少客户端请求新的 COM 对象,进程中将只有一个服务器.exe。 在服务器) 多个实例的单一使用 (中,对新 COM 对象的每个请求都会启动服务器.exe文件的单独实例。 因此,服务器的多个实例可以在同一台计算机上运行。

Word (Winword.exe) 、Excel (Excel.exe) 和 Microsoft Access (MSAccess.exe) 的多个实例可以同时运行。 因此,这些服务器定义为单一使用 (多个实例) 服务器。 只有一个 PowerPoint (Powerpnt.exe) 实例可以在任何给定时间运行。 因此,PowerPoint 是多用 (单实例) 服务器。

COM 服务器是单一使用 (多个实例) 还是多用 (单个实例) 可能会影响你使用 GetActiveObject 获取对该服务器的引用的决定。 由于可能运行 Word、Excel 或 Microsoft Access 的多个实例,因此特定服务器上的 GetActiveObject 可能会返回你未预料到的实例。 首次在 ROT 中注册的实例通常是 GetActiveObject 返回的实例。 如果要获取对 Word、Excel 或 Microsoft Access 的特定运行实例的自动化引用,请将 BindToMoniker 与在该实例中打开的文件的名称一起使用。 对于多用 (单实例) 服务器(如 PowerPoint)来说,这并不重要,因为自动化引用指向同一个正在运行的实例。

COM 服务器应在启动后在“正在运行的对象表”中注册。 当 Office 程序失去焦点时,将自行注册。 如果程序在程序失去焦点之前尝试附加到正在运行的实例,则可能会收到错误消息。

参考

有关使用 GetActiveObject 时 Office 程序的不同行为的其他信息,请单击下面的文章号,查看 Microsoft 知识库中的文章:

288902 信息:Office 自动化服务器的 GetObject 和 CreateObject 行为有关详细信息,请参阅以下 Microsoft 开发人员网络 (MSDN) 网站:

使用 Visual Studio 进行 Microsoft Office 开发