きよくらの備忘録

「三日坊主と呼ばせない!日記」改め。主にソフトウェア開発関連の話題。

Silverlight 4のOOBで他の実行ファイルを実行するテスト

Silverlight 4ではTrusted Applicationsという、権限を昇格させたモードが追加されていてます。

これは権限昇格をさせてOOB(out-of-browser)実行*1することで今までのsandbox制限をかなり取り払った形で動作するものとなっていて、例えば、COM(Component Object Model)にアクセスすることが出来ます。


と言うことは、COMさえ自作してしまえば割と何でも出来てしまう……例えば、任意の実行ファイルを実行する、なんていうことも出来てしまいます。

……ということで、試しにnodepad.exeをSilverlightアプリから起動させるサンプルを作ってみました。

0.仕組み

仕組みは前述したように、notepad.exeを実行するCOMを作成し、SilverlightアプリはそのCOMを操作する形です。
図にすると、以下のような形。

と言うことで、手順的には、
1.COMの作成
2.Silverlightアプリケーションの作成
という手順を踏みます。


※以降の手順はVisual Studio 2010 Beta2で行っています。

1.COMの作成

notepad.exeを実行するメソッドを公開するCOMを作っていきます。

1.1. プロジェクトの作成

Visual Studioを起動*2し、プロジェクトの新規作成を行います。


テンプレートは、「クラスライブラリ」を選択すれば良いでしょう。
名称は、今回は「NotepadExec」としておきます。
言語は何でもよいですが、今回はC#で作ってみます。

1.2. notepad.exeを実行するコードの追加

プロジェクトテンプレートが展開されたら、既定で存在しているClass1.csを開き、notepad.exeを実行するようなpublicメソッドを記述します。
例えば、以下のような感じ。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NotepadExec
{
    public class Class1
    {
        public void Execute()
        {
            System.Diagnostics.Process.Start("notepad.exe");
        }
    }
}
1.3. COM関係の設定

次に、COMとして使うための設定をします。

まずは、アセンブリ情報を編集し、『アセンブリをCOM参照可能にする』のチェックをonにします。
([プロジェクト]-[<プロジェクト名>のプロパティ]-[アプリケーション]タブ-[アセンブリ情報]ボタンで起動するダイアログにて設定)


次に、ビルド時にCOMを登録するように設定を行います*3
これも、プロジェクトのプロパティにて、『COM 相互運用機能の登録』のチェックを行えばOKです。
([プロジェクト]-[<プロジェクト名>のプロパティ]-[ビルド]タブにて設定)


この状態でビルドを実行すると、COMの登録まで完了します。
(OSや状態によっては、管理者権限でVSを起動していないとCOMの登録に失敗します。その場合はVSを管理者権限で起動し直してください。)

2.Silverlightアプリケーションの設定

フロントエンドとなる、Silverlightアプリケーションを作成していきます。

1.1. プロジェクトの作成

Visual Studioを起動し、プロジェクトの新規作成を行います。
Silverlightアプリケーション」テンプレートを選択し、名称は「NotepadExecSL」として作成します。
また、ウィザードに従い、ホストするWebアプリケーションプロジェクトも作成します。Silverlightのバージョンは、もちろん「Silverlight 4」です。

1.2. 参照設定

Microsoft.CSharpを参照設定に追加します。
これは、COMオートメーションのオブジェクトを作成する、ComAutomationFactory.CreateObject()の戻りを受ける為にdynamic型を使うためです。
私は最初は『参照設定でタイプライブラリを見ればよいのかなぁ』と思ったのですが、どうも上手く参照できない*4ので、参考にした例に従い、dynamic型で受けることにしました。

Microsoft.CSharpの参照の追加方法は、[参照の追加]でダイアログを表示、[参照]タブで[Microsoft.CSharp.dll]を選択すればOKです。
(Microsoft.CSharp.dllは、『C:\Program Files\Microsoft SDKs\Silverlight\v4.0\Libraries\Client\Microsoft.CSharp.dll』等にあります。)

1.3. ブラウザ外実行の設定

プロジェクトのプロパティから、ブラウザ外実行の設定を行います。
まずは、[Silverlight]タブの『アプリケーションのブラウザー外実行を有効にする』のチェックをonにし、ブラウザ外実行を可能にします。

次に、その隣の[ブラウザー外実行の設定]ボタンからダイアログを表示し、一番下にある『Requier elevated trust when running outside the browser』のチェックをonにします。
この設定をしないと、COMの呼び出し等、sandboxの制限外の操作ができません。

1.3. コードの記述

コードを記述していきます。
アプリケーションの作りとしては、ボタンを一つ配置し、ボタンをクリックしたらCOMからnotepad.exeを起動するようなアプリにしてみます。

MainPage.xamlに適当にボタンを配置(名前はbutton1)し、そのClickイベントハンドラに以下のコードを記述します。

private void button1_Click(object sender, RoutedEventArgs e)
{
    dynamic obj = System.Windows.Interop.ComAutomationFactory.CreateObject("NotepadExec.Class1");
    obj.Execute();
}

以上でコーディングは完了。
ビルドして実行してみます。

3.実行

実行し、画面が表示されたら右クリックでコンテキストメニューを表示し、ローカルインストールを実施します。

インストールを確認するダイアログが表示されます。

ちなみに、権限昇格させない(『Requier elevated trust when running outside the browser』のチェックがoff)の場合は、以下のようなダイアログになります。


インストールが完了すると、ブラウザ外モードでアプリケーションが実行されますので、後はボタンをクリックすると、見事(?)メモ帳が起動します。

4.まとめ

以上のように、COMを経由すると、簡単にSilverlightからローカルにインストールされているアプリケーションを実行する事が出来ました。
この権限昇格モードの存在により、COMで出来ることなら何でも出来る…と理解して良いのではないかと思います。


#これで、少なくとも社内業務アプリを作る上では、かなり死角が消えたような。

*1:ブラウザー外実行とも。

*2:このとき、Windows 7Vistaの場合、Visual Studioを『管理者として実行』すると良いです。理由は、後の行程でCOMを登録する際に、管理者の権限が必要になるためです。

*3:ビルドする環境でのみ有効です。もしビルドするマシン以外で実行する場合は、できあがったCOMをインストーラやバッチファイル等、何らかの手段で登録してやる必要があります

*4:Silverlight用のアセンブリしか参照できないからだと思います