トップ回答者
OCXの使用について

質問
-
開発環境
Windows8.1 Pro
VisualStudio2012
開発言語:VB
対象フレーム:.net Framework4.0
VB6.0にて作成されたOCXをVS2012にて使用したいと思っています。
プロジェクトの参照設定にてOCXを選択し、以下以下のように記述し実行したところ
「COMExeptionはハンドルされませんでした。 致命的なエラーです。 (HRESULT からの例外:0x8000FFFF (E_UNEXPECTED))」
とエラーが出てしまいます。
Class Main
Private _lib As New TestLib.TestLib
Private Sub btnTest_Click(sender As Object, e As RoutedEventArgs) Handles btnTest.Click
_lib.RunAAA ←ここでエラー
End Class
因みに
VB6.0にて対象のOCXを参照し、ActicexDllを作成
作成されたDLLをレジストリ登録
VB2012にて参照とした場合は問題なく使用できたのですが、
「実行するPCが多いために各PCにレジストリ登録をすることができない」
と言われたため、困っているところです。
以上、ご教授の程、よろしくお願い致します。
回答
-
OCXもしくはCOMの一般論として、レジストリ登録は結果の一つであって、正確にはDllRegisterServer entry pointを実行する必要があります。「regsvr32 DLL名」を実行するのはそのためです。
ですので、この関数内にレジストリ登録以外にも何らかの初期化処理が含まれていた場合、レジストリ登録だけを行っても正常動作しない可能性があります。では今回の質問の環境はというとVB6で作成したOCXとのことなので、DllRegisterServerには自動生成分だけで独自の初期化処理を含まない可能性もあります。その場合はレジストリだけが書き込まれていればいいわけなので、プログラムがOCXを呼び出す前にRegistryクラスなどを用いて書き込んでやれば条件が満たされるという考え方もできます。
その場合はさらにIsolated Applications and Side-by-side Assembliesを使うことでmanifestファイルにOCXの情報を記述することで、レジストリでなくmanifestファイルを参照させることも可能かもしれません。とはいえ、どのようなレジストリを書けばいいのかなど把握できていないと思いますので、VB6のOCXを使用せず新規にVS2012で書き直すことをお勧めします。
- 回答としてマーク onionsword 2014年9月11日 6:28
-
スレの本題とは無関係なのですが訂正しておく必要があると感じたので。
COMのレジストリ登録は結果ではなくシステム要件です。ただし、現在は例外がありそれが .manifest ファイルに登録しておく手段です(Side-by-side Assembliesと呼ばれる利用形式。ちなみに、この .manifest ファイルを持つexeを、Isolated Appliation(分離アプリ)と呼ぶ。詳しくは佐祐理さんのリンク先を参照)。
ちなみに、レジストリ登録の手段として現在主流を占めているのは自己登録と呼ばれる方式です。主流というよりおそらく現行で動くものならすべてのCOMオブジェクト(OLEを含む)が、自己登録ルーチンを持っていると思います。
ただし、この自己登録もCOMができた当初からあったわけではなく、OCXができた時代に、一緒に追加された仕組みで、開発中のOCXを速やかに使えるようにと編み出された手法の一つでしかありません。
それと、自己登録処理でCOM情報の登録以外の処理を行うのは今も昔も推奨されていません。
とっちゃん@わんくま同盟, Microsoft MVP for Visual C++ (Oct 2005-) http://blogs.wankuma.com/tocchann/
- 回答としてマーク onionsword 2014年9月11日 6:29
-
自己登録処理でCOM情報の登録以外の処理を行うのは今も昔も推奨されていません。
反論ではありませんが、これってどこかで言及されているのでしょうか?
ちなみにWindows Installer databaseにはもちろんSelfRegテーブルもありますが、TypeLib、ProgId、Classテーブルなどが用意されているため自己登録以外の方法もそこそこ認められているのかと思っていました。
# 推奨してないならRegistryテーブルでちまちま登録させてもいいわけで…- 回答としてマーク onionsword 2014年9月11日 6:29
-
なんだか誤解があるような感じです。
少なくとも私には、「自己登録で、「COM情報の登録以外の処理」を行う→昔から非推奨」と読め、
「「自己登録でCOMの登録を行う」以外(の登録方法)は昔から非推奨」ではないはずです。なお、「自己登録でCOMの登録を行う」こともWindowsInstaller的には非推奨です。(SelfRegテーブルのRemarkによれば)
jzkey
- 回答としてマーク onionsword 2014年9月11日 6:29
-
DllRegisterServer で、COMの登録以外の処理も出来るが推奨されていないということが言いたかったんですが。。。なんかどうとでも取れてしまう文章ですね。申し訳ないです。
と、書いてる間にコメントされてたw
現在ある推奨されていないという部分では、SelfReg Table が一番簡潔にまとまってると思います。
昔の部分は、Inside OLE でインストールすることに対する部分で書かれていた気がします。手元にないので確認とれてませんが...OLE 2.0 のプログラマーズガイドはまだ自己登録そのものがなかった気がするので。。。
古くからある問題ですが、これも一種の DLL-Hell 問題で、インストール時に上書きできずにリブートする場合、登録処理もリブート後に行わないと正しく動作しない場合があるため、推奨できない(ただし、当時の貧弱なインストーラでそれを実現するのは困難を伴っている個所があったため、あまり言及できないともあったはず)とされていたはずです。
とっちゃん@わんくま同盟, Microsoft MVP for Visual C++ (Oct 2005-) http://blogs.wankuma.com/tocchann/
- 回答としてマーク onionsword 2014年9月11日 6:29
すべての返信
-
OCXもしくはCOMの一般論として、レジストリ登録は結果の一つであって、正確にはDllRegisterServer entry pointを実行する必要があります。「regsvr32 DLL名」を実行するのはそのためです。
ですので、この関数内にレジストリ登録以外にも何らかの初期化処理が含まれていた場合、レジストリ登録だけを行っても正常動作しない可能性があります。では今回の質問の環境はというとVB6で作成したOCXとのことなので、DllRegisterServerには自動生成分だけで独自の初期化処理を含まない可能性もあります。その場合はレジストリだけが書き込まれていればいいわけなので、プログラムがOCXを呼び出す前にRegistryクラスなどを用いて書き込んでやれば条件が満たされるという考え方もできます。
その場合はさらにIsolated Applications and Side-by-side Assembliesを使うことでmanifestファイルにOCXの情報を記述することで、レジストリでなくmanifestファイルを参照させることも可能かもしれません。とはいえ、どのようなレジストリを書けばいいのかなど把握できていないと思いますので、VB6のOCXを使用せず新規にVS2012で書き直すことをお勧めします。
- 回答としてマーク onionsword 2014年9月11日 6:28
-
スレの本題とは無関係なのですが訂正しておく必要があると感じたので。
COMのレジストリ登録は結果ではなくシステム要件です。ただし、現在は例外がありそれが .manifest ファイルに登録しておく手段です(Side-by-side Assembliesと呼ばれる利用形式。ちなみに、この .manifest ファイルを持つexeを、Isolated Appliation(分離アプリ)と呼ぶ。詳しくは佐祐理さんのリンク先を参照)。
ちなみに、レジストリ登録の手段として現在主流を占めているのは自己登録と呼ばれる方式です。主流というよりおそらく現行で動くものならすべてのCOMオブジェクト(OLEを含む)が、自己登録ルーチンを持っていると思います。
ただし、この自己登録もCOMができた当初からあったわけではなく、OCXができた時代に、一緒に追加された仕組みで、開発中のOCXを速やかに使えるようにと編み出された手法の一つでしかありません。
それと、自己登録処理でCOM情報の登録以外の処理を行うのは今も昔も推奨されていません。
とっちゃん@わんくま同盟, Microsoft MVP for Visual C++ (Oct 2005-) http://blogs.wankuma.com/tocchann/
- 回答としてマーク onionsword 2014年9月11日 6:29
-
自己登録処理でCOM情報の登録以外の処理を行うのは今も昔も推奨されていません。
反論ではありませんが、これってどこかで言及されているのでしょうか?
ちなみにWindows Installer databaseにはもちろんSelfRegテーブルもありますが、TypeLib、ProgId、Classテーブルなどが用意されているため自己登録以外の方法もそこそこ認められているのかと思っていました。
# 推奨してないならRegistryテーブルでちまちま登録させてもいいわけで…- 回答としてマーク onionsword 2014年9月11日 6:29
-
なんだか誤解があるような感じです。
少なくとも私には、「自己登録で、「COM情報の登録以外の処理」を行う→昔から非推奨」と読め、
「「自己登録でCOMの登録を行う」以外(の登録方法)は昔から非推奨」ではないはずです。なお、「自己登録でCOMの登録を行う」こともWindowsInstaller的には非推奨です。(SelfRegテーブルのRemarkによれば)
jzkey
- 回答としてマーク onionsword 2014年9月11日 6:29
-
DllRegisterServer で、COMの登録以外の処理も出来るが推奨されていないということが言いたかったんですが。。。なんかどうとでも取れてしまう文章ですね。申し訳ないです。
と、書いてる間にコメントされてたw
現在ある推奨されていないという部分では、SelfReg Table が一番簡潔にまとまってると思います。
昔の部分は、Inside OLE でインストールすることに対する部分で書かれていた気がします。手元にないので確認とれてませんが...OLE 2.0 のプログラマーズガイドはまだ自己登録そのものがなかった気がするので。。。
古くからある問題ですが、これも一種の DLL-Hell 問題で、インストール時に上書きできずにリブートする場合、登録処理もリブート後に行わないと正しく動作しない場合があるため、推奨できない(ただし、当時の貧弱なインストーラでそれを実現するのは困難を伴っている個所があったため、あまり言及できないともあったはず)とされていたはずです。
とっちゃん@わんくま同盟, Microsoft MVP for Visual C++ (Oct 2005-) http://blogs.wankuma.com/tocchann/
- 回答としてマーク onionsword 2014年9月11日 6:29