Visual C# を使用して Office プログラムの実行中のインスタンスを自動化する方法

概要

このステップバイステップの記事では、Office プログラムの実行中のインスタンスへの Automation リファレンスを取得する Microsoft Visual C# 2005 または Microsoft Visual C# .NET クライアントを作成する方法について説明します。

Office プログラムの実行中のインスタンスを自動化する Visual C# 2005 または Visual C# .NET アプリケーションを作成する

Office を自動化するクライアント プログラムでは、その Office プログラムの新しいインスタンスを作成するか、既に実行されているインスタンスへの参照を取得できます。 Microsoft では通常、実行中のインスタンスにアタッチするのではなく、新しいインスタンスを作成することをお勧めします。 ただし、一部のシナリオでは、クライアント プログラムで Office プログラムの既に実行されているインスタンスを自動化する必要があります。 この場合、Automation クライアントは、実行中のオブジェクト テーブル (ROT) から Automation サーバーのコンポーネント オブジェクト モデル (COM) オブジェクトへの参照を取得します。

Automation サーバーが実行中のオブジェクト テーブルに登録されている場合、.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. [参照の追加] ダイアログ ボックスで、[OK] をクリックして選択内容を受け入れます。

  3. [表示] メニューの [ツールボックス] をクリックしてツールボックスを表示します。 Form1 に 3 つのボタンとテキスト ボックスを追加します。 これらのコントロールのテキストを次のように入力します。

    ID テキスト
    button1 実行中の Excel インスタンスに対する Automation リファレンスを取得する
    button2 File Moniker を使用して Excel へのオートメーションリファレンスを取得する
    button3 Shell Word と Get Automation Reference to it
    textBox1 保存した xls ファイルのファイル名を入力します
  4. 次のように、ボタン コントロールの Click イベント ハンドラーを設定します。

    1. button1 をダブルクリックし、[表示] メニューの [デザイナー] をクリックします。
    2. button2 をダブルクリックし、[表示] メニューの [デザイナー] をクリックします。
    3. button3 をダブルクリックします。
  5. Form1.cs の先頭に次のコードを追加し、他の using ステートメントの後に追加します。

    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 の既存のインスタンスへの Automation 参照を取得します。 Automation 参照は、button1_Clickのローカル変数 oExcelApp に格納されます。 メッセージ ボックスに、作業中のブックの名前が表示されます。
  6. ブックをローカル ディスクに保存します。 Excel でブックを開いたままにします。
  7. textBox1 で前の手順で保存したブックの完全なパスとファイル名を入力します。
  8. [ File Moniker を使用して Excel へのオートメーションリファレンスを取得する ] ボタンをクリックします。
  9. アプリケーションは、実行中の Excel インスタンスへの Automation 参照を取得します。 Automation リファレンスは、ローカル変数 xlwkbookfor button2_Clickに格納されます。 作業中のシートの最初の行と最初の列に 100 の値が入力されます。
  10. ブックに変更を保存せずに Excel を終了します。
  11. [ File Moniker を使用して Excel へのオートメーションリファレンスを取得する ] ボタンをクリックします。
  12. Excel の新しいインスタンスが作成され、以前に保存したブックが開きます。 アプリケーションは、Excel のこのインスタンスへの Automation 参照を取得します。 Automation リファレンスは、button2_Clickのローカル変数 xlwkbook に格納されます。 作業中のシートの最初の行と最初の列に 100 の値が入力されます。
  13. Excel を閉じます。
  14. [Shell Word と Get Automation Reference to it] ボタンをクリックします。
  15. Word は、コマンド プロンプトから起動した場合と同様に起動し、起動された Word メッセージ ボックスが表示されます。 メッセージ ボックスを表示すると、WM_SETFOCUSメッセージが強制的に Word プログラム ウィンドウに送信されます。 これにより、Word は実行中のオブジェクト テーブル (ROT) に自身を登録できます。
  16. メッセージ ボックスを閉じます。 プログラムは、Word の新しく開始されたインスタンスへの Automation 参照を取得します。 Automation 参照は、button3_Clickのローカル変数 wdapp に格納されます。 Word.Application オブジェクトの名前を示すメッセージ ボックスが表示されます。

追加情報

COM サーバーは、1 台のコンピューターで同時に実行できるそのサーバーのインスタンスの数に応じて、Multiuse (単一インスタンス) または単一使用 (複数インスタンス) として分類できます。

新しい COM オブジェクトの要求が Multiuse (Single Instance) COM サーバーに送信されると、サーバーは.exe ファイルのインスタンスを 1 つだけ使用してそのオブジェクトを作成します。 新しい COM オブジェクトを要求するクライアントの数に関係なく、プロセス.exeサーバーは 1 つだけです。 単一使用 (複数インスタンス) サーバーでは、新しい COM オブジェクトに対する各要求によって、サーバー .exe ファイルの個別のインスタンスが開始されます。 そのため、サーバーの複数のインスタンスを同じコンピューターで実行できます。

Word (Winword.exe)、Excel (Excel.exe)、Microsoft Access (MSAccess.exe) の複数のインスタンスを同時に実行できます。 そのため、これらのサーバーはシングル ユース (複数インスタンス) サーバーとして定義されます。 特定の時点で実行できる PowerPoint (Powerpnt.exe) のインスタンスは 1 つだけです。 そのため、PowerPoint は Multiuse (シングル インスタンス) サーバーです。

COM サーバーが単一使用 (複数インスタンス) であるか Multiuse (単一インスタンス) であるかは、GetActiveObject を使用してそのサーバーへの参照を取得するという決定に影響を与える可能性があります。 Word、Excel、または Microsoft Access の複数のインスタンスを実行できる可能性があるため、特定のサーバー上の GetActiveObject は予期しないインスタンスを返す可能性があります。 ROT に最初に登録されるインスタンスは、通常、GetActiveObject によって返されるインスタンスです。 Word、Excel、または Microsoft Access の特定の実行中のインスタンスに対する Automation Reference を取得する場合は、そのインスタンスで開かれているファイルの名前と共に BindToMoniker を使用します。 PowerPoint のような Multiuse (Single Instance) サーバーの場合、オートメーション参照が同じ実行中のインスタンスを指しているため、問題ありません。

COM サーバーは、起動時に実行中のオブジェクト テーブルに自身を登録する必要があります。 Office プログラムは、フォーカスが失われると自分自身を登録します。 プログラムがフォーカスを失う前に実行中のインスタンスにアタッチしようとすると、エラー メッセージが表示されることがあります。

関連情報

GetActiveObject を使用するときの Office プログラムのさまざまな動作の詳細については、以下の記事番号をクリックして、Microsoft サポート技術情報の記事を参照してください。

288902 INFO: Office Automation サーバーの GetObject と CreateObject の動作の詳細については、次の Microsoft Developer Network (MSDN) Web サイトを参照してください。

Visual Studio を使用した Microsoft Office Development