次の方法で共有


Microsoft Application Virtualization

仮想化環境でアプリケーションに Windows 7 との互換性を持たせる

Chris Jackson

Windows 7 を完全にサポートする Microsoft Application Virtualization (App-V) 4.6 が間もなくリリースされます。Windows 7 の展開を予定している多くのユーザーが、App-V をデスクトップ変革プロジェクトに使用するコンポーネントに含めています (OS の展開は、"最新のデスクトップ" や "次世代のデスクトップ" の構想においてアプリケーションとインフラストラクチャの両方の全面的な見直しと組み合わせて行われることがよくあります)。

IT プロフェッショナルが App-V への投資と Windows 7 への投資を組み合わせることについて考える際は、次の疑問がほぼ必ず会話に出てきます。

  • App-V はアプリケーション互換性ソリューションだと聞いているが、それはつまり、App-V を使用してアプリケーションに Windows 7 との互換性を持たせることができるということなのか。
  • 現在使用している Windows XP デスクトップ用に既に作成した App-V パッケージを再びシーケンスする必要があるのか。
  • App-V を展開ソリューションとして使用する場合に、互換性のないアプリケーションを修正するにはどうすればよいか。

これらの質問それぞれについて考えてみましょう。

Microsoft App-V はアプリケーション互換性ソリューションなのか

Microsoft App-V は、まず第 1 に、アプリケーションの管理と展開のためのソリューションで、パッケージ化のコストを削減し、システムの安定性を向上させ、ソフトウェア資産に動的にアクセスする移動の多い最近の従業員をサポートするという形で、企業に大きなメリットをもたらします。しかし、マーケティング上のメッセージ伝達の一環として、過度の負担をかけられた "アプリケーション互換性" という言葉が時間の経過と共に誤って解釈されるようになり、App-V はアプリケーションと OS との間の互換性の問題を解決するのに役立つのだと誤解されるようになってきました。ほとんどの場合、App-V はこのような問題を解決するのには役立ちません (現在、例外はありますが、それはほぼ歴史上の理由により存在するものであり、当てにするべきものではないので、ここでは詳細については説明しません)。

ユーザーの混乱を招くことになってしまったため、マーケティング メッセージの明確化が図られ、"アプリケーション互換性" という言葉を使うのを控えて、代わりに、"アプリケーション間の競合が軽減され (互換性という言葉が戦略的に除外されていることに注目してください)、その結果、回帰試験が大幅に減少する" という基本的なメリットを直接伝えるようになりました。

アプリケーションと OS の互換性に関する製品チームの公式見解は次のとおりです。

前述のとおり、App-V は、アプリケーションと OS の互換性のための汎用的なソリューションではありません。ただし、アプリケーション互換性 shim を適用することでアプリケーションを特定の Windows バージョン上でネイティブに (仮想化せずに) 動作させることが可能であれば、shim が適用されたそのアプリケーションが仮想化されている場合、そのアプリケーションはほとんどの場合、また、ほとんどの shim に関して、App-V と連携します。したがって、原則として、shim が適用されたアプリケーションが、対象となるバージョンの OS 上でネイティブに動作することができる限り、App-V は、アプリケーションとマイクロソフトのアプリケーション互換性ツールの一部として提供されている shim との併用をサポートします。

このように、App-V がアプリケーションと OS の互換性のためのソリューションとして作られたものではないことは非常に明白です (shim と App-V の併用については後で説明します)。アプリケーションの仮想化が OS の互換性に与えるその他の影響について見てみましょう。

Microsoft App-V はパッケージ互換性ソリューションなのか

アプリケーション互換性について語る際は、パッケージ互換性を実行時互換性と切り離す必要があります。実際、推奨されるアプリケーション互換性テスト プロセス (2009 年 6 月号の私の記事「アプリケーション互換性プロジェクトを計画する」の図 3 参照) では、インストール テストと実行時テストが切り離されています。まずは、製品チームの公式なガイダンスを見てみましょう。

ある OS 上でシーケンスを行い、仮想化されたアプリケーションを別の OS 上で実行するというのはよくあるシナリオです。しかし、このシナリオはアプリケーションと OS の両方に依存しており、すべてのアプリケーション/OS の組み合わせに対して機能するとは限りません。App-V は汎用的な OS 互換性ソリューションではないためです。問題が発生した場合、ユーザーは、問題を解決するために、App-V クライアントが実行されているのと同じ OS 環境でシーケンスを行うことを求められる可能性があります。

あまり期待の持てそうな話ではありませんね。要するに、"場合による" というのが公式見解なのですから。ですが、リスクの測定について考えている場合は、現在使用されている次の 3 つの主なセットアップ テクノロジを比較してみてください。

Setup.exe: このテクノロジでは任意のコードが実行されるので、そのコードでは、アプリケーション自体の任意のコードで発生する可能性のあるものと同じ実行時の問題が発生する可能性があります。そのため、実行するコードを徹底的にテストする必要があります。

Windows インストーラー: このテクノロジでも、インストールを実行するためのコードが実行されますが、このコードの大部分は構造化された宣言型のコードです。任意のコードはカスタム動作を示す命令型のコードのみなので、データベースに対して実行されるコードとカスタム動作の任意のコードの処理に影響を与える、定量化可能なルール変更を除けば、Setup.exe よりも互換性は (完ぺきではありませんが) 高く、テストは少なくて済むでしょう。

Microsoft App-V: このテクノロジでは、コードを実行する必要はまったくありません。単に、ひとかたまりのデータ (仮想ファイル システム) がコピーされ、"使用する仮想ファイル システムはここ" と指定されるだけです。したがって、一番の問題は、アプリケーションがインストールされるかどうかではなく (ひとかたまりのデータをコピーするのは、結局のところ、非常に簡単です)、アプリケーションの実行時互換性です。そのため、インストール テストは 3 つのテクノロジの中で最も短くなるでしょう。これはうれしいですね。

というわけで、パッケージはすべて機能すると公式に発言する人はいませんが、多くの人がインストールの問題と実行時の問題をひとまとめに考えていることが公式なメッセージの主な理由のようです。一般に、既に Microsoft App-V に投資している場合は、アプリケーション インストール テストの予想されるコストが大幅に削減されることを期待できます。

Microsoft App-V を使用してアプリケーションをパッケージ化する場合に実行時互換性の問題を修正するにはどうすればよいか

サポート声明の中の、"…App-V は、アプリケーションとマイクロソフトのアプリケーション互換性ツールの一部として提供されている shim との併用をサポートします。" という興味をかきたてる部分を覚えていますか。これを実際に実装するにはどうすればよいのでしょうか。App-V と shim は本質的に互換性があるのでしょうか。

さいわい、答えはイエスです。実際、これを行うためのいくつかの異なる選択肢が存在します。

簡単な shim 入門

shim についてよく知らない方のためにご説明すると、shim は、マイクロソフトで使用される 4 文字の単語のうち、何かの頭字語ではない非常に数少ない単語の 1 つです。これは、英語の shim (くさび) という単語に基づくメタファーです。元になる英単語は、2 つの物がよりぴったり組み合わさるようにその 2 つの間に挿入される木片や金属片を表現するために使用される工学用語です。この場合は、2 つの物はアプリケーション プログラムと Windows で、shim の材料は、2 つがより適切に連携して動作するようにする追加のコードです (図 1図 2 参照)。

 

図 1 shim を適用する前は、アプリケーションは Windows と直接対話する

 

 

図 2 shim の適用後は、アプリケーションは Windows と間接的に対話する (挿入された shim コードでは、Windows への要求、Windows からの応答、またはその両方に変更を加えることができる)

shim は、API インターセプトを使用して機能します。Windows API は、DLL のコレクションを使用して実装されています。Windows 向けに構築された各アプリケーションはこうした DLL をインポートし、こうした関数それぞれのアドレスが格納されたテーブルをメモリ内に保持します。Windows 機能のアドレスはテーブル内にあるので、shim エンジンは、このアドレスを簡単に shim DLL のアドレスに置き換えることができます。アプリケーションは一般に、要求が Windows 自体ではなく shim DLL に送信されていることを認識せず、Windows は、要求がアプリケーション以外の送信元から来ていることを認識しません (shim DLL はアプリケーションのプロセス内の DLL の 1 つにすぎないため)。

たとえば、非常によく使用される shim の 1 つに、バージョン偽装 shim があります。この shim を実装するには、アプリケーションがどのバージョンの Windows 上で実行されているかを特定するために使用されるいくつかの API をインターセプトします。通常、この情報は Windows 自体に渡され、Windows が正しい答えを返します。しかし、バージョン偽装 shim が適用されると、こうした API がインターセプトされます。要求は Windows に渡されず、実際と異なる Windows のバージョンが返されます (たとえば、Windows 7 の代わりに Windows XP が返されます)。アプリケーションが Windows XP 上でのみ動作するようにプログラミングされている場合、この方法を使用して、実際はそうでなくても、適切な OS 上で実行されているとアプリケーションに認識させることができます (多くの場合、これだけでアプリケーション互換性の問題が解決されます)。

shim を使用して行うことができる偽装は非常にたくさんあります。以下に例を示します。

  • ForceAdminAccess shim は、現在のユーザーがローカル Administrator グループのメンバーでなくても、メンバーであるとアプリケーションに認識させようとします (ユーザーがローカル管理者でない場合、多くのアプリケーションは完全に、機能しなくなります。ただし、UAC のファイルおよびレジストリの仮想化など、他の方法を使用して、チェックが行われるそもそもの原因となった問題を解決できる場合もあります)。この shim がこのチェックを実装する方法は非常に簡単な場合があります。たとえば、この shim は、shell32.dll の IsUserAnAdmin という API をインターセプトします。shim が適用された関数 (実際の API と比べるとパフォーマンス特性が非常に優れています) の全ソース コードは単に、"return TRUE;" です。
  • WrpMitigation shim は、Windows リソース保護 (WRP) によって保護されているファイルへの書き込みを行うことができるという錯覚をアプリケーション インストーラーに与えます。保護されているファイルに書き込みを行おうとすると、この shim は、まず新しい一時ファイルを作成し、ハンドルが閉じられたら削除されるようにそのファイルをマークし、続いて、保護されている実際のファイルであるかのようにして一時ファイルへのハンドルを返します。アプリケーションは古いバージョンの kernel32.dll や shell32.dll (または、パッケージ化されている間に選択されたその他のファイル) を一時ファイル内にインストールしますが、その後、その一時ファイルは削除され、更新プログラムが適用された最新バージョンの適切な保護されたファイルがファイル システム上に残ります。したがって、この shim を使用すると、Windows 95 の古い shell32.dll のコピーがコンピューター上に残らないようにしながら、インストーラーが ACCESS_DENIED で失敗することを回避することができます。
  • CorrectFilePaths shim では、ファイルをある場所から別の場所にリダイレクトすることができます。したがって、c:\myprogramdir への書き込みを行おうとするアプリケーションがある場合 (これは UAC のファイルおよびレジストリの仮想化を使用して自動的に修正されません)、実行時に変更が加えられるファイルをユーザーごとの場所にリダイレクトすることができます。こうすると、アクセス制御リスト (ACL) の制限を緩和することなく (セキュリティ担当者はユーザーが ACL の制限を緩和するのを嫌がるので)、標準ユーザーとしてアプリケーションを実行することができます。

アプリケーション互換性の問題を解決するために使用できる汎用的な shim は何百個も存在し、こうした修正を利用できるとコストが大幅に削減される場合があります。たとえば、shim は次のような場合によく使用されます。

  • ベンダーが倒産してしまったので、更新されたバージョンを入手することができない。新たなベンダーから別のアプリケーションを入手したり、新しいバージョンを自分で構築したりする余裕がない場合は、このアプローチを使用するとある程度時間を節約することができます。
  • 当該のアプリケーションは、(サポート声明付きの) 更新されたバージョンに投資するほど重要ではないが、ユーザーがそう希望しているので、サポートされていないバージョンをユーザーが実行してもかまわない。
  • アプリケーションは組織内で開発されたが、完全に更新されたバージョンをチームがリリースするまで待つのではなく、一時的な修正を適用し、永続的な修正は開発チームがアプリケーションの予定されている次期リリースと同時にリリースする方がよい。このアプローチを使用すると、すべてのアプリケーション開発作業を停止して互換性バグの修正に時間とリソースをつぎ込む必要はなくなります。一時的な修正を適用し、チームが既に開発を進めている新機能に関する修正はチームがリリースするようにすることができます。

アプリケーション互換性アプローチの一環として shim を活用すると、大幅なコスト削減につながったり、Windows 7 の展開にかかる時間が大幅に短縮されたりする場合があります。

企業で shim を管理する場合の選択肢

2007 年 11 月に公開された、企業での shim の管理に関するホワイト ペーパーで、私は、組織でアプリケーション互換性ソリューションとして shim を管理する方法を決める際にほとんどの人がどちらかを選ぶ 2 つの主な選択肢について概説しました。簡単に要約すると、この 2 つの選択肢は次のようなものです。

一元管理された単一の shim データベース: この選択肢では、shim を必要とするすべてのアプリケーション用のエントリを格納する一元管理された単一の shim データベースを展開します。その後、修正が必要なアプリケーションがさらに見つかったら、中央のデータベースに更新プログラムを追加することができます。これは、マイクロソフトが使用しているアプローチです。マイクロソフトは、Windows 7 を、何千個ものアプリケーションを修正するシステム shim データベースと共に出荷しました。そして、修正が必要なアプリケーションがさらに見つかったら、Windows Update を通じて更新プログラムをデータベースに追加します。皆さんも同じことを行うことができます。shim データベースをマスター イメージに格納し、システム管理ソフトウェア (System Center Configuration Manager など) を通じて更新するのです。

アプリケーションごとの shim データベース: もう 1 つの選択肢としては、アプリケーションの修正をアプリケーションと共に直接展開することもできます。修正が必要なアプリケーションが 1 つか 2 つしかない場合はこの方法を選択するユーザーもいます。小規模な環境では、中央のデータベースを管理するためのプロセスを構築するよりも、この方がコストが少なくて済むからです。アプリケーションごとの shim データベースの大きなデメリットは、なんらかの問題があると、shim データベースを更新するのが困難になることです。ですが、App-V では、アプリケーションごとのデータベースを更新し、更新されたバージョンをユーザーに配信することができるようになったので、この欠点が解消されます (ただし、後でわかるように、これによって、別のはるかに大きな欠点がもたらされます)。

Microsoft App-V がソフトウェアの展開に使用するアプローチは、アプリケーションの修正を企業全体に展開するために使用できる選択肢の幅を広げ、ユーザーは組織で現在使用されているプロセス モデルに最も合ったアプローチを選択することができます。

一元管理された単一の shim データベースを使用して App-V アプリケーションに shim を適用する

では、戦術的な観点から考えると、一元管理された単一の shim データベースを展開し、これが App-V を使用してシーケンスされたアプリケーションによって認識されるようにするには、どうすればよいのでしょうか。答えは簡単です。単に、通常どおりにインストールすればよいのです。App-V を使用してインストールされたアプリケーションは、通常とほぼ同じ方法で起動され、shim が適用される同じローダー メカニズムを使用します。単に、サロゲート プロセスによって起動されるだけです。具体的に言うと、エクスプローラーではなく sfttray.exe によって、新しいプロセスを起動するための処理が行われます。したがって、プロセス ツリーは図 3 のようなものになります。

 

図 3 サロゲート プロセス ツリー

アプリケーションは、起動されると、その他のアプリケーションと同様に、ローダーを通じて実行されます。Microsoft Application Virtualization Client Interface Layer (sftintf.dll) が CreateProcessW を呼び出し、CreateProcessW は内部の CreateProcessInternalW API を呼び出します。CreateProcessInternalW API 内で、shim エンジンが起動され shim がプロセスに関連付けられます。

かなり簡単ですね。何か問題点はあるのでしょうか。1 つあります。昇格がうまく処理されないことです。たとえば、単純に (RunAsAdmin shim を使用して) アプリケーションの昇格を求めたり、ElevateCreateProcess を使用して昇格を必要とするアプリケーションの問題を修正したりすることはできません。その理由は、バブルです。

たとえば、自動自己更新を起動しようとするアプリケーションを例にとってみましょう (残念ながら、これは非常によくあるタスクです)。このアプリケーションをネイティブに実行した場合、昇格を起動することができない CreateProcess API が使用されるという問題があったとします。そして、アプリケーションは "-1073740756 – STATUS_ELEVATION_REQUIRED" というエラーを返します。ElevateCreateProcess shim がこの戻り値を受け取り、昇格を提供するためにアプリケーション情報サービスを起動します。しかし、このサービスはバブルの外にあるので、昇格するアプリケーションを検出することができません。

以上のことからわかるように、アプリケーションが昇格を必要としない限り、作り上げたプロセスが既にある場合は単一の shim データベースのソリューションを展開するのは簡単です。単に同じことを繰り返せばよいからです。

アプリケーションごとの shim データベースを使用して App-V アプリケーションに shim を適用する

アプリケーション互換性の問題を解決するために shim を展開する別の方法は、shim をアプリケーションと共に展開するというものです。MSI を使用する場合は、通常、.sdb ファイルをインストーラーに含め、出力された .sdb ファイルに対して sdbinst を呼び出すカスタム動作を実装します。これにより、カスタム shim データベースがインストーラーの一部としてインストールされます (その後、そのアプリケーションの shim を更新する必要がある場合は、インストールされたクライアントをすべて探し出して、更新プログラムをインストールするためのスクリプトを実行する必要があり、事態は少し複雑になります)。

App-V を使用して、ほぼ同じことを行うことができます。.sdb ファイルがバブルの中に存在するようにするために、shim データベース (.sdb) ファイルをシーケンス自体に含めることができます。まず、適切に機能するには shim が必要なアプリケーションを、シーケンスします。それが済んだら、カスタム shim データベースを system32 に格納します。

(通常、私は、Steve Ballmer の下で働いていて Steven Sinofsky の管理下にいる方でなければ system32 には絶対に物を格納しないように勧めていますが、この場合に限っては、スクリプトの記述を簡単にするため、こうすることにしました。system32 はパス上にあり、実際に運用システム上の system32 内に何かを置くわけではなく、仮想ファイル システムにとって system32 のように見えるものの中に置くだけだからです)。

これが済んだら、.sprj ファイルを編集します。[Virtual File System] (仮想ファイル システム) タブに移動し、[View] (表示) メニューの [Virtual File System] (仮想ファイル システム) をポイントし、[Add] (追加) をクリックします。次に、.sdb ファイルを出力した場所 (c:\windows\system32\appshim.sdb) を参照し、[OK] をクリックします。これで、この .sdb ファイルはバブル内に存在するようになり、Softgrid パッケージのインストール時にインストールされます。このファイルはコンテナーの一部なので、アプリケーションの一部として持ち運ばれます (そして、アプリケーションを更新する際に更新することができます)。

もちろん、.sdb ファイルがファイル システム上にあるだけではアプリケーションの修正を適用することはできません。このファイルをインストールする必要があります。ただし、shim データベースは App-V バブルの外にインストールする必要があります。shim データベースをバブル内にインストールすると、仮想化された .sdb ファイルは、プロセスの作成が完了するまで検出可能な状態になりません。プロセスが作成された後で shim エンジンがこのファイルを検出して処理するのでは、遅すぎます。プロセスの作成中に、バブルの外にあるローダーが shim データベースにアクセスできるようにする必要があります。

さいわい、App-V には、アプリケーション起動プロセスの一環としてスクリプトを実行するメカニズムが含まれています。お好きなテキスト エディターを使用してアプリケーションの OSD ファイルを見てみると、このファイルが編集可能な XML にすぎないことがわかります。<SOFTPGK> 要素の中には、<IMPLEMENTATION> 要素、<DEPENDENCY> 要素、<PACKAGE> 要素、<ABSTRACT> 要素、<MGMT_SHORTCUTLIST> 要素、および <MGMT_FILEASSOCIATIONS> 要素があります。編集するのは <DEPENDENCY> 要素です。カスタム shim データベースのインストールを実行するための <SCRIPT> という子要素を追加します。アプリケーションの起動時にカスタム shim データベースをインストールし、アプリケーションの終了時に再びこのデータベースを削除することができるスクリプトの例を以下に示します (App-V の重要な目標の 1 つである、"立つ鳥跡を濁さず" 型の JIT インストールです)。

<DEPENDENCY>       <CLIENTVERSION VERSION="4.6.0.0"/>       <SCRIPT EVENT="LAUNCH" PROTECT="TRUE" TIMING="PRE" WAIT="TRUE" EXTERN="TRUE">              <SCRIPTBODY LANGUAGE="Batch">sdbinst /q appshims.sdb</SCRIPTBODY>       </SCRIPT>       <SCRIPT EVENT="SHUTDOWN" PROTECT="TRUE" TIMING="POST" WAIT="TRUE" EXTERN="TRUE">              <SCRIPTBODY LANGUAGE="Batch">sdbinst /u appshims.sdb</SCRIPTBODY>       </SCRIPT>
</DEPENDENCY>

このスクリプトでは、App-V バブルの外から shim データベース インストーラー (sdbinst.exe) を呼び出していますが、引数として、App-V バブルの中に存在するためアプリケーション展開シーケンスの一環として展開される .sdb を使用しています。したがって、アプリケーションの修正をアプリケーションのその他の部分と同じように簡単に展開および更新することができます。

カスタム shim データベースのインストールは、管理者権限を必要とするプロセスです。このデータベースを実行時にインストールするのは問題でしょうか。ユーザーに管理者権限を要求しなくても済むことが望ましく、ユーザーも、アプリケーションを起動するたびに UAC ダイアログでクリックを行わなければならないのは避けたいと思っています。さいわい、これを行う必要はありません。sdbinst.exe の呼び出しは自動的に昇格されます。shim のインストールのプロセス ツリーを図 4 に示します。

 

 

図 4 shim インストール プロセス ツリー

コマンド シェルが作成され、続いて、カスタム shim データベースをインストールするために sdbinst.exe を呼び出します。これが STATUS_ELEVATION_REQUIRED で 2 回失敗してから、昇格を提供するサービスであるアプリケーション情報サービスが呼び出されます。このサービスは consent.exe を呼び出し、consent.exe はアプリケーションを昇格するべきかどうかを判断するためにポリシーをチェックします。(仮想環境内の) ポリシーは、ユーザーに対するプロンプトを表示することなくイエスの返事を返します。consent.exe は昇格を承認し、sdbinst.exe の昇格されたインスタンスが作成され、カスタム shim データベースをインストールします。ただし、プロンプトを表示することなく昇格するというポリシーは、ユーザーが昇格を行うことができる場合にのみ確認なしで機能することに注意してください。標準ユーザーの場合、アプリケーションを起動したり終了したりするたびに、管理者の資格情報を求めるプロンプトが表示されます。これは標準ユーザーの環境においてきわめて望ましくないことと見なされる可能性が高いので、このアプローチは、ローカル管理者ユーザーを展開した場合にのみ機能します。これが当てはまるユーザーの割合がきわめて少ないことを願っています。

まとめ

Microsoft Application Virtualization は、アプリケーションの管理と展開のための強力なツールです。Windows 7 への移行計画にこのツールを取り入れると、インストール テスト中のコストが削減される可能性があります (ただし、このコストがゼロになると保証されるわけではありません)。

また、shim を使用してアプリケーション互換性の問題を解決するためのプロセスのほとんどを引き続き活用することができます。組織規模の単一の shim データベースを展開する場合、変化はごくわずかです。(App-V 環境で昇格全般を避けるのとほぼ同様にして) 昇格 shim を避けるように気を付けてさえいれば問題ありません。アプリケーションごとの shim を展開する場合、shim データベースをアプリケーションと共にパッケージ化し展開する簡潔な方法がいくつかありますが、管理者以外のユーザーとしてアプリケーションを満足に実行することができないという非常に大きな欠点があります。そのため、(MSI ベースのアプリケーション展開の場合と同様に、) 一元管理された単一のデータベースとして shim を展開するよう努めることを強くお勧めします。このようなデータベースは既存のシステム管理ソフトウェアを使用して展開することができます。こうすることにより、管理者以外のアカウントで実行するユーザーの割合がますます増えていく将来に目を向けることができるようになります。

Chris Jackson ("アプリケーション互換性の男") はマイクロソフトのプリンシパル コンサルタントで、Windows Application Experience SWAT チームのテクニカル リードも務めています。Jackson は Windows アプリケーションの互換性の分野で広く知られている専門家で、企業顧客や独立系ソフトウェア ベンダーと実際に何年もかかわってきた経験に基づいて、マイクロソフト内や外部で使用される技術文書、トレーニング、およびサービスを作成しています。Jackson には、人気のブログ (英語) を通じて連絡を取ることができます。

関連コンテンツ