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で出来ることなら何でも出来る…と理解して良いのではないかと思います。
#これで、少なくとも社内業務アプリを作る上では、かなり死角が消えたような。
*2:このとき、Windows 7やVistaの場合、Visual Studioを『管理者として実行』すると良いです。理由は、後の行程でCOMを登録する際に、管理者の権限が必要になるためです。
*3:ビルドする環境でのみ有効です。もしビルドするマシン以外で実行する場合は、できあがったCOMをインストーラやバッチファイル等、何らかの手段で登録してやる必要があります
*4:Silverlight用のアセンブリしか参照できないからだと思います