KB 2517589 / 2640696 : Win7 SP1 上でビルドした ADO を参照するプログラムが下位バージョン OS 上で動作しない現象と対処方法 (Ver 2.1)

横井 羽衣子
SQL Developer Support Engineer

※ Tue, Apr 3 2012 Ver 1.0 / Published
※ Tue, May 2 2012 Ver 2.0 / ADO PIA についての言及を追記
※ Tue, Oct 23 2012 Ver 2.1 / 動作概念図追記および現象発生しない場合についての言及追記

今回は、サポート技術情報 2517589 の現象についてのご案内です。    
この技術情報は、Windows 7 Service Pack 1 または Windows Server 2008 R2 Service Pack 1 上でビルドした ADO を参照する Visual C++ アプリケーションや、Visual Basic for Applications (VBA) マクロを下位バージョンの OS 上で実行すると、エラーが発生するという現象について記載しています。
また、すでに製品サポートは終了しておりますが、VBA と同様に Visual Basic 6.0 アプリケーションにおいても発生します。
この問題に対し、012 年 2 月 14 日にサポート技術情報 2640696 と修正モジュールがリリースされました。
本問題についての動作と、対処方法について解説いたします。

※注 / ADO プライマリ相互運用アセンブリ (PIA) について 本問題の対処方法(2640696 内容含む)につきましては、サポート技術情報 2517589 の文書の最初のセクション( “Caution” 部分)にてご案内しておりますように、プライマリ相互運用アセンブリ (PIA) 経由で ADO を利用されたケースではなく、C++ / Visual Basic for Applications (VBA) を対象としております。ADO PIA は .NET Framework のいわゆるマネージ層のテクノロジとは異なり、ADO など、COM オブジェクトを直接参照することができるアンマネージのテクノロジをマネージのテクノロジから利用する際、ADO のプライマリ相互運用アセンブリ (PIA) である Interop.ADODB.dll を通じて参照するという動作になるため、C++ / VBA の場合と仕組みが異なります。この場合、後述の msado15.dll の直接参照ではなく、タイプライブラリの参照を実施いただく必要があります。ただし、上述のように C++/VBA と比較して、テストシナリオが多くはないことにご注意ください。弊社といたしましては、段階的な移行として ADO PIA の回避を実施されたのちは、可能な限り早急に ADO.NET へ移行を実施されることを推奨いたします。

Caution ADO and ADO MD have not been fully tested in a Microsoft .NET Framework environment. They may cause intermittent issues, especially in service-based applications or in multithreaded applications. The techniques that are discussed in this article should only be used as a temporary measure during migration to ADO.NET. You should only use these techniques after you have conducted complete testing to make sure that there are no compatibility issues. Any issues that are caused by using ADO or ADO MD in this manner are unsupported. For more information, see the following article in the Microsoft Knowledge Base:

840667 (https://support.microsoft.com/kb/840667/ ) You receive unexpected errors when using ADO and ADO MD in a .NET Framework application

問題の概要

この現象は、Windows 7 Service Pack 1 に含まれる ADO の各オブジェクトの GUID に変更が行われ、Windows 7 サービス パック無しのバージョン以前の OS の GUID と異なる値になったことに起因して発生します。  
Windows 7 Service Pack 1 の環境で ADO のライブラリを参照し、コンパイルしますと、変更後の GUID がビルド後のモジュールに埋め込まれます。この状態のモジュールを、Windows 7 サービス パック無しの環境や、Windows XP 上などで実行しますと、実行環境の ADO のオブジェクトの GUID は、モジュール内に埋め込まれた Windows 7 Service Pack 1 の環境の ADO の GUID と合致しないため、エラーが発生します。

Article ID: 2517589 - Last Review: January 17, 2012 - Revision: 7.0
An ADO application does not run on down-level operating systems after you recompile it on a computer that is running Windows 7 SP 1 or Windows Server 2008 R2 SP 1 or that has KB983246 installed
https://support.microsoft.com/kb/2517589/en-us     

修正モジュールの公開先について

Article ID: 2640696 - Last Review: February 14, 2012 - Revision: 1.0
An ADO-based application that is compiled in Windows 7 SP1 or in Windows Server 2008 R2 SP1 does not run in earlier versions of Windows
https://support.microsoft.com/kb/2640696

※基本的に上記修正モジュールは、Visual C++ もしくは Visual Basic for Applications を対象にして検証しました。Visual Basic 6.0 はサポートライフサイクル終了のため検証は行っていません。適用の結果動作するかどうかお試しいただくことは切り分けとして有効です。

エラーの一例

・実行時エラー'430':クラスはオートメーションまたは予測したインターフェースをサポートしていません。
・Run-time error '430': Class does not support Automation or does not support expected interface.
・REGDB_E_CLASSNOTREG (0x80040154)
・E_NOINTERFACE (0x80004002)
・E_POINTER (0x80004003)

現状サポート対象となる OS で変更を行っておりますのは Windows 7 Service Pack 1 のほか、Windows Server 2008 R2 SP1 です。  
そのため、この 2 つの OS で Microsoft ActiveX Data Objects に参照設定を行い、コンパイルしたプログラムをこれ以前の OS (Windows 7 サービス パック無し ~ Windows XP などのそれ以前の OS) で動作させた場合に本現象が発生します。  

発生シナリオ例

1. Windows 7 Service Pack 1 上で ADO を参照した VBA マクロを持つ Office ファイルを作成する
2. Windows Vista と、Windows 7 Service Packなしの環境ともう一つ別の Windows 7 Service Pack 1 環境上に作成した Office ファイルを配置する
3. それぞれの環境で実行する   

image

Windows Vista エラー 430 発生
Windows 7 Service Pack なし エラー 430 発生
Windows 7 Service Pack 1 正常実行可能

     

原因

ADOのオブジェクトのメソッドやプロパティの内部実装において、一部、64 bit に対応していないものが存在するため、環境によっては型不一致のエラーが発生します。そこで、64 bit に対応し、32 bit および 64 bit のいずれでも動作するための仕様変更として、新たなインターフェースを作成し、その新しいインターフェースに新しい GUID を割り当てるという手法による対応を Windows 7 SP1 にて実施しました。 
また、以前からのインターフェースについては、例えば Connectionクラスであれば、Deprecated という接尾辞をつけ、こちらを以前からの GUIDに割り当てています。  

そのため、Windows 7 SP1 にて ADO のオブジェクトを事前バインド(Early Bind)で使用するアプリケーションをビルドした場合、新しいインターフェース (GUID) を使用することとなり、このアプリケーションを Windows 7 SP1 より前の OS で動作させた場合、該当する GUID が存在しないためにエラー 430 が発生するようになりました。

■ Excel マクロ使用時の問題発生例

1. Excel マクロでデータベースを利用するための機能 (ADO) を使用するように構成して保存すると、保存した環境の OS に含まれる、機能を識別する情報を Excel マクロ ブックに埋め込みます。Windows 7 SP1 以降から、この ADO の識別情報が変更されました。そのため、ADO の識別情報は、Windows 7 SP1 にしかない情報が埋め込まれてしまいます。

clip_image001[5]

図 : Excel マクロ作成マシン上の動作 : マシンが Windows 7 SP1 以降の場合

※上記図では識別情報を便宜上、1234-4567 としていますが、実際にはもう少し複雑な GUID と呼ばれる識別子となります。また、Windows 7 SP1 は、それより前の OS に含まれる ADO の識別情報も持っています。

2. Windows XP など、Windows 7 SP1 以前のバージョンの OS 上に、Windows 7 SP1 で保存した Excel マクロ ブックを保存すると、Excelマクロブックに埋め込まれた ADO の識別情報を取り出し、実行環境のOS に含まれる識別情報と一致するか照会します。

clip_image001[3]

図 : Excel マクロ実行マシン上の動作 : Windows 7 SP1 未満のバージョンの OS の場合 (1)

3. Windows XP SP3 に含まれる ADO の識別番号は、実は0123-4567 であり、Windows 7 SP1 の ADO の識別番号の 1234-4567 とは異なります。よって、Windows 7 SP1 の新しい識別情報と合致する識別情報がExcel マクロブックを開いた環境のレジストリにありませんので、処理は失敗してしまいます。

clip_image001[1]

図 : Excel マクロ実行マシン上の動作 : Windows 7 SP1 未満のバージョンの OS の場合 (2)

■ 補足 : 状況によって発生しないこともあるがその条件は制御できない

なお、ファイルの開き方などによって、マクロ内に保持された情報ではなく、動作環境の情報が読み込まれることがあります。これにより、現象が発生しない場合もあります。

しかし、動作環境の情報を読み込ませる条件も複数あり、かつそれがユーザあるいはマクロ開発者によってコントロールできる条件ではないため、事実上修正モジュールを適用すること以外に確実に今回の問題を制御する方法はありません。 よって、タイプ ライブラリを参照される場合も、DLL を直接参照してマクロを作成される場合も、サポート技術情報 2640696 の修正モジュールの適用を頂くという回答に変わりはございません。

対処方法

Windows 7 SP1 および Windows Server 2008 R2 環境に対して適用するための修正プログラムが作成され、サポート技術情報 2640696 にて公開されました。モジュールには 32bit 版と 64bit 版が存在しますので、お使いの環境に対してモジュールをダウンロードし、適用します。
適用後、必ず参照設定を新しいライブラリに変更し、あらためてアプリケーションの再コンパイルを実施し、実行環境に配置します。
再コンパイルを実施しない場合は、エラーは継続して発生しますのでご注意ください。

※ Point ※ なお、修正モジュールの適用対象は、アプリケーションをビルドする環境(もしくは VBA マクロを持つ Office ファイルを保存する環境)であり、これらのアプリケーションや、マクロを実行する環境側には適用の必要はありません。 Article ID: 2640696 - Last Review: February 14, 2012 - Revision: 1.0 An ADO-based application that is compiled in Windows 7 SP1 or in Windows Server 2008 R2 SP1 does not run in earlier versions of Windows https://support.microsoft.com/kb/2640696

例) Visual Basic for Applications の場合

1. ダウンロードしたモジュールをダブルクリックして実行し、インストールします。
   

imageimage

2. [開発] タブを開き、[Visual Basic] をクリックします。

image

        ※開発タブがない場合は、[ファイル] タブの [オプション] をクリックし、[リボンのユーザー設定] – 右ペインの [開発] をチェックして、[OK] を押します。 

image

image

3. [ツール(T)] - [参照設定(R)] を選択します。

image

4. [参照設定] ダイアログが開きますので、まず、以下のチェックボックスを外します。

Microsoft ActiveX Data Objects 6.0 Library
場所 : C:\Program Files\Common Files\System\ado\msado60.tlb

image

※参考 : モジュール適用前の参照設定の状態です。参照先が C:\Program Files\Common Files\System\ado\msado15.dll となっています。サポート技術情報 2640696 のモジュールを適用した後は、上記のように msado60.tlb に自動的に参照先が変わります。

image

5. "Microsoft ActiveX Data Objects 6.0 Library" のチェックを外しましたら、[参照(B)] を押し、以下の DLL を参照します。

    C:\Program Files\Common Files\System\ado\msado15.dll

image

6. [参照設定] ダイアログに戻ります。"Microsoft ActiveX Data Objects 6.1 Library" が出現しますので、こちらのチェックをつけて、[OK] を押します。

image

7. [ファイル(F)] - [<ファイル名> の上書き保存(S) Ctrl+S] を選択し、保存します。
8. ブックを保存します。
9. Windows 7 Service Pack 1 よりも前のバージョンの OS にファイルをコピーし、実行します。

なお、再コンパイル(保存)後のファイルの参照設定を Windows Vista 上で見ても、参照先はMicrosoft ActiveX Data Objects 6.0 Library のままです。

image

※ 参考 : 修正モジュールが適用できない要件のビルド環境の場合の回避手段

この現象は、遅延バインドにコードを変更いただくことで回避可能です。
以下の技術情報にて、コード例を紹介しておりますので、ご参照下さい。 
 
[INFO] オートメーションにおける事前バインディングおよび実行時バインディングの使用 
https://support.microsoft.com/kb/245115/ja 
 
オブジェクト変数を "Object" として宣言していただくことで、遅延バインドになります。なお、事前バインディングと実行時バインディングで異なるのは、変数の宣言のみです。