Active X コントロールコンテナがない

今更なのですが、Active X コントロールの相談を受けました。
既存の Active X コントロールを IE8 で検証したら、まったく動かないということで
IE8 用に再設計すると…。Visual Studio 2008 で Active X なんて作ったことないので、すごーく久々です。
VC++6.0 では COM 大好きでよく作ったものです…。
VC++6.0 の頃と COM に関する IDE 操作もずいぶんと変わっていました。

とりあえず、HelloWorld レベルの HelloActiveX っていうサンプルを作っていろいろと思い出そうとしているのですが
いきなり、以前、テストでよく使った Active X コントロールコンテナが無いことに気がつきました。
調べたところ、Visual Studio 2008 には無いと…。ではどうするのかと言うと

  1. Visual C++ 2008 のサンプルをダウンロード
  2. Active X コントロールコンテナ を自分でビルド

するということが判明。

参考情報

1) サンプルをダウンロードする

ダウンロードして、vc_sample.exe を実行すると、インストーラーが走り、AllVCLanguageSamples.zip というファイルができますので
これを展開します。

2) ビルド方法

インストールフォルダ\C++\MFC\ole\TstCon

にある ソリューションファイル TstCon.sln を Visual Studio 2008 で開きます。すると 2 つのプロジェクトが入っています。
まず、TstCon プロジェクト内にあるヘッダーファイル StdAfx.h を開きます。
そこに、

1:  #ifndef WINVER
2: #define WINVER 0x0500
3: #endif

を追加します。

同じように TXProps プロジェクトにある ヘッダーファイル StdAfx.h にもある定義も同様にします。

次にプロジェクトのプロパティを開き、リンカのマニフェストファイルにある ”UAC を有効にする” を「いいえ」にします。

これで準備完了です。
あとは、ソリューションプラットフォームを Win32 にしてビルドすることで、Active X コントロールコンテナができます。

おお~、久々だ。
Active X コントロールにはデジタル署名を付与しないと動かないってことも忘れずに。

Visual Studio 2008 SP1 に Windows SDK v6.1 を登録すると?

  1. Visual Studio 2008 SP1 を Vista x86 にインストール (フルインストール)
  2. Windows SDK v6.1 (Windows SDK for Windows Server 2008 and .NET Framework 3.5) をインストール
  3. Microsoft Windows SDK v6.1 – Visual Studio Registration – Windows SDK Configuration Tool を実行する

…とクラッシュします。あれ!?

Windows SDK Configuration Tool というのは、WindowsSdkVer.exe です。
(Microsoft SDKs\Windows\v6.1\Setup にあります)
直接 v6.1 を指定して

WindowsSdkVer -version:v6.1

実行しても

というエラーになります。あれれ!?
ハマりました。で、対応ですが、

に記述されていました。
VS2008 がインストールする Windows SDK 6.0A のレジストリ登録に問題があるらしく、
これを自分で直してしまえば良いと。私の環境では

HKLM\Software\Microsoft\Microsoft SDKs\Windows\v6.0a@ProductVersion = 6.0A

になっていました。これを

HKLM\Software\Microsoft\Microsoft SDKs\Windows\v6.0a@ProductVersion = 6.0.6001.17011

に変更しました。
で、Windows SDK Configuration Tool (WindowsSdkVer.exe) を実行すると無事に起動できました。

回避策を探すまで 2 時間くらいかかってしまいましたが、こういう情報って、もっとわかりやすいところに
置いてほしいですね。

Visual Studio 2008 SP1 のライブラリにバインドしたい

すでに Visual Studio 2008 には SP1 がリリースされているわけですが、SP1 をインストールした環境で
アプリケーションをビルドしても、埋め込みマニフェストに出力されるライブラリは Visual Studio 2008 RTM 版(9.0.21022.8)の
ままになっています。
この仕様が良いか悪いかの議論はあると思いますが、オプションを用いることで特定のライブラリにバインドさせることが
できます。

てっとり早く書いておくと、stdafx.h の先頭に

#define _BIND_TO_CURRENT_VCLIBS_VERSION 1

と追加しておくと、開発環境で使用しているライブラリのバージョンがマニフェストに記述されるというわけです。

#define _BIND_TO_CURRENT_VCLIBS_VERSION 1 の定義が無い場合

  <dependency>
    <dependentAssembly>
      <assemblyIdentity type=’win32′ name=’Microsoft.VC90.CRT’ version=’9.0.21022.8‘ …
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type=’win32′ name=’Microsoft.VC90.MFC’ version=’9.0.21022.8‘ …
    </dependentAssembly>
  </dependency>

#define _BIND_TO_CURRENT_VCLIBS_VERSION 1 の定義がある場合

  <dependency>
    <dependentAssembly>
      <assemblyIdentity type=’win32′ name=’Microsoft.VC90.CRT’ version=’9.0.30729.1‘ …
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type=’win32′ name=’Microsoft.VC90.MFC’ version=’9.0.30729.1‘ …
    </dependentAssembly>
  </dependency>

あとは使用するライブラリを再頒布すれば、期待した動作になると思います。
ただし、ATL プロジェクトの場合には注意が必要です。
Visual Studio 2008 SP1 で「_BIND_TO_CURRENT_VCLIBS_VERSION 1」がある場合でも
マニフェストには、9.0.30729.1 と 9.0.21022.8 の CRT にバインドするように作成してしまいます。

ATL プロジェクトの場合

#define _BIND_TO_CURRENT_VCLIBS_VERSION 1 の定義が無い場合

  <dependency>
    <dependentAssembly>
      <assemblyIdentity type=’win32′ name=’Microsoft.VC90.CRT’ version=’9.0.21022.8‘ …
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type=’win32′ name=’Microsoft.VC90.ATL’ version=’9.0.21022.8‘ …
    </dependentAssembly>
  </dependency>

#define _BIND_TO_CURRENT_VCLIBS_VERSION 1 の定義がある場合

  <dependency>
    <dependentAssembly>
      <assemblyIdentity type=’win32′ name=’Microsoft.VC90.CRT’ version=’9.0.30729.1‘ …
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type=’win32′ name=’Microsoft.VC90.ATL’ version=’9.0.30729.1‘ …
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type=’win32′ name=’Microsoft.VC90.CRT’ version=’9.0.21022.8‘ …
    </dependentAssembly>
  </dependency>

いまいち、はっきりしない仕様ですが、結局のところ、Visual Studio 2008 SP1 でATL プロジェクトを作成したら、
9.0.30729.1 と 9.0.21022.8 の CRT を再頒布しないと動かないってことです。

2009 年もマイペースで更新しますので、よろしくお願いします。