Windows XP がもたらす Visual Basic デベロッパーへの福音
~ 第 2 回: 新しいサイド バイ サイド技術 ~
Shozo Arai (荒井 省三)
マイクロソフト株式会社
デベロッパー・マーケティング本部
February 7, 2002
目次
はじめに
COMCTL32.DLL バージョン 6
ActiveX DLL でのサイド バイ サイドの利用
まとめ
次回について
はじめに
前回は Windows XP の視覚スタイルの概要と Visual Basic 6.0 を使って 視覚スタイルを利用した Visual Basic アプリケーションの作成方法と問題点を説明しました。今回は、視覚スタイルの裏側で活躍している COMCTL32.DLL バージョン 6 や Windows 2000 から更に進化したサイド バイ サイド技術の説明と Visual Basic で作成する ActiveX DLL において、どのような恩恵があるかを説明いたします。
COMCTL32.DLL バージョン 6
Windows XP では、COMCTL32.DLL のバージョン 6 が新しく導入されています。この COMCTL32.DLL を使って 視覚スタイルを表示しています。テーマの切り替えは、テーマ マネージャ Uxtheme.dll を通じて COMCTL32.DLL のバージョン 6 とバージョン 5 を切り替えることで行っているのです。COMCTL32.DLL のバージョン 5 (図 1 ) とバージョン 6 (図 2 ) について説明します。Windows 2000 のコントロールでは、
図1. Windows 2000 のコントロール
図 2. Windows XP のコントロール
USER32.DLL、WIN32.SYS や COMCTL32.DLL バージョン 5 にコントロールが組み込まれています。Windows XP では、USER32.DLL、WIN32.SYS や COMCTL32.DLL バージョン 5 に含まれているコントロールを統合した COMCTL32.DLL バージョン 6 が存在します。Windows XP では、明示的に COMCTL32.DLL バージョン 6 を使用すると宣言しない限り、COMCTL32.DLL バージョン 5 が使用されます。このように、COMCTL32.DLL の複数バージョンがサイド バイ サイド技術を使って共有されています (Windows 2000 では、EXE 名 .local というファイルを配置することでサイド バイ サイドを実現していました。詳しくは 「アプリケーションで共有するサイド バイ サイドコンポーネントの実装 (拡張)」 をご参照ください)。この技術は、.NET Framework をフルサポートすることを目標に DLL Hell の解消、バージョン競合の解消、容易な配置、容易な環境設定 (NoMore リブート) をサポートすることを前提にしています。この目標を達成するために Windows XP では、COMCTL32.DLL バージョン 6 や GDI + 等を共有アセンブリとして組み込んでいます。共有アセンブリのインストール場所は「%SYSTEMROOT%\WinSxS」です (通常は、C:\Winnt\ WinSxS です)。共有アセンブリと従前の %SYSTEMROOT%\SYSTEM32 にインストールされる共有 DLL の主要なものを表1に抜粋します。
配置場所 | サブディレクトリー又はファイル名 | 説 明 |
WinSxS | Manifests | 共有コンポーネントのマニフェスト |
x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.0.0_x-ww_1382d70a | COMCTL32.DLL V6コンポーネント | |
x86_Microsoft.Windows.GdiPlus_6595b64144ccf1df_1.0.0.0_x-ww_8d353f13 | GDI+コンポーネント | |
x86_Microsoft.Windows.CPlusPlusRuntime_6595b64144ccf1df_7.0.0.0_x-ww_2726e76a | VC++のランタイム | |
x86_Microsoft.Tools.VisualCPlusPlus.Runtime-Libraries_6595b64144ccf1df_6.0.0.0_x-ww_ff9986d7 | ||
x86_Microsoft.Tools.VisualCPlusPlus.Runtime-Libraries.Resources_6595b64144ccf1df_6.0.0.0_ja-JP_8a84acaa | ||
System32 | COMCTL32.DLL | COMCTL32.DLL V5コンポーネント |
MSVCRT.DLL | VC++のランタイム |
表1.共有アセンブリの抜粋
共有アセンブリが導入されたことにより、VC++ のランタイムや COMCTL32.DLL を原因とする DLL の競合は解決されます (思い起こせば、IE3.X がリリースされたときの問題が解消されるのです)。このサイド バイ サイドの仕組みをご覧になられた方は、「あれ?」と思われたかもしれません。「マニフェスト」「アセンブリ」という用語をどこかでお聞きになられた方達も多いことと思います。そうです、.NET Framework の配布単位がアセンブリと呼ばれ、アプリケーションの自己記述情報 (バージョン情報や関連モジュール情報等) がマニフェストと呼ばれていたのです。この サイド バイ サイド技術は、Windows 2000 と Windows 98 Second Edition に始まり、.NET Framework 向けに進化し、Windows XP で Platform 向けに最適化されて進化してきたのです。
WinSxS にインストールされる共有アセンブリは、.NET Framework と同様にストロングネームを必要とします。インストールするには、Windows Installer でインストールを行う必要があります。このように共有アセンブリは厳密に管理されますので、DLL の競合が発生する可能性を低くすることが可能になるのです。後は、皆さんが配布されるアプリケーションのインストールフォルダに共有コンポーネントも一緒に配布して、アプリケーション マニフェストを配置すれば DLL Hell から脱出することが可能になります。今後は、%SYSTEMROOT%\SYSTEM32 フォルダに共有コンポーネントを配布しないようにすれば良いのです。ここまで読まれた方たちは、「関数をエキスポートできるダイナミックリンクライブラリは Windows 2000 でも実現されていたし、COM に関してはどうなんだ?」 という疑問を持たれたことと思います。Windows 2000 では DLL/COM リダイレクションがありましたが、Windows XP では更に進化した COM のサポートがあります。
ActiveX DLL でのサイド バイ サイドの利用
これから Visual Basic で作成する ActiveX DLL のサポート (COM のサポート) がどうなったのかについて説明していきたいと思います。手始めに、簡単な ActiveX DLL (リスト 1 ) と利用する Visual Basic アプリケーション (リスト 2 ) を作成してみます。このアプリケーション (Project1.exe) を実行した様子を図 3 に示し、レジストリの情報を図 4 に示します。
Public Function Add(ByVal lngA As Long, ByVal lngB As Long) As Long
' ActiveX DLLの例
' 加算結果を戻すメソッド
'
Dim lngResult As Long
lngResult = lngA + lngB
MsgBox "結果=" & CStr(lngResult), vbOKOnly, "Side-by-Side Comへようこそ"
Add = lngResult
End Function
リスト 1. ActiveX DLL (プロジェクト名: ComTest、クラス名 : SideBySide)
Private Sub Command1_Click()
' ActiveX DLLを利用するアプリケーション
' ProgId=ComTest.SideBySide を使用する
'
Dim objComTest As ComTest.SideBySide
Dim lngResult As Long
Set objComTest = New ComTest.SideBySide
lngResult = objComTest.Add(CLng(txtA.Text), CLng(txtB.Text))
txtResult.Text = CStr(lngResult)
Set objComTest = Nothing
End Sub
リスト 2. ActiveX DLL を利用する Visual Basic アプリケーション (プロジェクト名 : Project 1 )
図3. Visual Basic の ActiveX DLL を実行したところ
図4. ComTest.SideBySide のレジストリ登録情報
図 3 と図 4 を見れば、VB で作成した ActiveX DLL の動作としては当たり前の動作をしていることをご理解いただけることと思います。それでは、コマンドプロンプトで 「Regsvr32.exe /u ComTest.dll」 を実行し、その結果のレジストリ登録情報を図 5 に示します。
図5. ActiveX DLL を削除した状態のレジストリ情報
図 5 を見ると、きれいにレジストリの登録情報が削除されていることがわかると思います (Windows 2000 までは、レジストリにキーのみのゴミが残っていたことをご存知の方も多いかと思います)。これで、さきほどの 「Project1.exe」 を実行しても、実行することはできなくなります (図 6)。この動作は、レジストリに ActiveX DLL の登録情報がありませんので当然のこととご理解いただけると思います。
図6. Project1.exe の実行時エラー
次に、アプリケーション マニフェストをリスト 3 のように記述します。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0" processorArchitecture="X86"
name="Microsoft.SidebySide.Test" type="win32" />
<description>サイドbyサイドのテスト(XP)</description>
<file name="ComTest.dll">
<comClass
clsid="{12A129C3-E5E5-4635-894F-BE4EAB24CA68}"
progid="ComTest.SideBySide" />
</file>
</assembly>
リスト 3. ActiveX DLL で使用するアプリケーション マニフェスト
マニフェストに記述したクラス ID は、レジストリエディタか OLE VIEW (Visual Studio6.0 に付属) で調べることができます (筆者の環境では、OLE VIEW で調査しました。レジストリエディタでは、HKEY_CLASSROOT\Prog Id\CLSID キーで調査します)。これで、ActiveX DLL を使用するアプリケーション 「Project1.exe」 を実行してみます (図 7)。
図7. マニフェスト記述後の実行例
図 3 と同じように実行できたことが確認できたと思います。この時のレジストリ情報を検索しても、図 5 と同様にレジストリに登録情報を発見することはできませんでした。Windows 2000 の COM リダイレクションでは、.local を配置していましたがレジストリ登録情報を必要としていました。明らかに、Windows 2000 のサイド バイ サイド技術より進化しているのが伺えることと思います。
では、ダイナミックリンクライブラリを明示的にマニフェストで指定するにはどうすれば良いのでしょうか。マニフェストの具体例をリスト 4 に示します。このように指定すれば、アプリケーションのインストール
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0" processorArchitecture="X86"
name="Microsoft.SidebySide.Test" type="win32" />
<description>サイドbyサイドのテスト(XP)</description>
<file name="msvcrt.dll"/>
<file name="msvcrt40.dll"/>
</assembly>
リスト 4. プライベートダイナミックリンクライブラリの指定
フォルダにインストールしたダイナミックリンクライブラリを明示的に指定することが可能となるのです。ここまで説明してきたマニフェストに記述するノードを表 2 で説明します。
ノード/アトリビュート名 | 備 考 | |
AssemblyIdentity | アプリケーション毎に一つ。 dependencyAssembly ノードのノードしては、サイド バイ サイド使用のアセンブリを指定します。 | |
version | アプリケーションやサイド バイ サイドアセンブリのバージョンで、メジャー.マイナー.ビルド.リビジョンを指定します。 | |
peocessorArchitecture | 「x86」か「ia64」を記入します。 | |
name | 一意になるアプリケーション名 (組織.部門.アプリケーション名) かアセンブリ名を指定します。 | |
type | アプリケーションタイプを指定します。「win32」 | |
publicKeyToken | 16 文字の SHA-1 ハッシュ値を指定します。 | |
language | 言語識別子を指定します (DHTML の言語コードです)。「*」 | |
dependencyAssembly | サイド バイ サイド使用するアセンブリを dependencyAssembly ノードを使って指定します。 | |
file | COM やプライベートアセンブリ (MSVCRT.DLL 等) を指定するノードです。 | |
name | ファイル名を指定します。 | |
comClass | COM の場合に、file ノードの子ノードとして COM 関係の情報を以下のアトリビュートで指定します。 | |
description | 説明。例えば、「Font Property Page」など。 | |
clsid | クラス ID を指定します。 | |
progid | プログラムID (COM のフレンドリー名)を指定します。 | |
thredingModel | スレッドモデルを指定します。例えば、「Both」など。 | |
tlbid | タイプライブラリ ID を指定します。 | |
version | バージョンを指定します。 | |
helpdir | ヘルプファイルのフォルダを指定します。 |
表 2. マニフェストの記述内容の説明 (抜粋)
表 2 で説明したアトリビュートは全てが必須ということではありません。リスト 3 のように省略も可能です。マニフェストの XML のエンコード (<?xml version="1.0" encoding="UTF-8"?>) には UTF-8 が指定されていますが、Windows XP では UTF-8 と UTF-16 がサポートされています (お勧めは UTF-8 ですが)。ここで説明した以外に、COM のサポートがマニフェストにあります。それは、ProxyStub を使用する COM コンポーネントです。ProxyStub を使用する COM コンポーネントの場合には、「comInterfaceExternalProxyStub」 ノードを記述することで対応することができます。更に、COMCTL32.DLL のようなコントロールであれば 「windowClass」 アトリビュートを指定して、特定のウインドウクラスのみを使用させることもできます。これらの指定方法は、ここでは説明を割愛させていただきますので、ご興味のあるかたは MSDN オンラインの記事 「How To Build and Service Isolated Applications and Side-by-Side Assemblies for Windows XP」をご参照下さい。
今回のまとめ
如何でしたでしょうか。VB で作成した ActiveX DLL がレジストリを使わないで動作したことをご理解いただけたことと思います。Windows XP のサイド バイ サイド技術は、Windows 2000 を第一世代とするならば格段に向上しているのがご理解いただけたと思います。完成した ActiveX DLL と Visual Basic アプリケーションの配布ですが、アプリケーション マニフェストと一緒にインストールフォルダにコピーするだけで動作します (但し、「VB6.0 のランタイムが配布されていれば」との条件がつきますが)。つまり、.NET Framework が提唱する XCOPY ライクな配布が限定的ながら実現されているのが、ご理解いただけることと思います。つまり、COM や DLL のバージョン毎の整合性の確認の工数を格段に減らす手段ができたということです。
最後になりましたが、XCOPY ライクな配布が限定的と申し上げましたのは、Windows XP で採用されたサイド バイ サイド技術で XCOPY ライクな配布が実現できるアプリケーションは、スタンドアロン形式の実行モジュール (EXE) だけになります。Active Server Pages などの世界には、まだ適用することができません。ですが、読者の皆様が作成された過去の Visual Basic アプリケーションを Windows XP へ安全に移行する手段が存在することを本コラムを通じて、ご理解頂けたのではないかと思います。Windows XP へ移行される場合は、アプリケーション マニフェストを記述して、十分なテストを行うことだけです。本コラムは 「Windows XP がもたらす Visual Basic プログラマーへの福音」と題してお届けしています。もう皆様には、お解かりのことと思いますが、「福音」とは、視覚スタイルを Visual Basic の生産性を活かして活用する方法とサイド バイ サイドを利用しての容易な配布が実現できることを指して名付けました。つまり、DLL Hell の解消が一歩進んだことを皆さんに、お知らせしたかったのです。
次回について
次回で本コラムは最終回になります。第 1 回で 視覚スタイルを取り上げ、第 2 回でサイド バイ サイドを取り上げました。次回は、.NET Framework を含めて新しい開発環境である Visual Studio.NET とサイド バイ サイドの将来性についても触れていきたいと考えております。それでは、次回まで、しばしのお別れです。
Shozo Arai: マイクロソフトのテクニカルエバンジェリストとして、デベロッパー向けに .NET Framework 技術を中心とした啓蒙活動をしています。現在注目しているのは .NET におけるスケーラビリティの向上技術や互換性技術です。
ページのトップへ