質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.37%

管理者で実行しているのに「モジュール xxxxx.ocx は読み込まれましたが、DllRegisterServer への呼び出しはエラーコード 0x800040200 により失敗しました。」が発生する

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 5,498

score 17

■ドライバ作成環境
OS: Windows 10 Pro (64bit) (ver.1803)
Tools: Visual Studio Professional 2017 (ver.15.7.4)+WDK10

ドライバ作成環境にてビルドした 32bit用ドライバ(2 projects: xxxxx.ocxとxxxxx.dll)を、
同じソリューション内で作成したインストーラを使用し、
Windows 10 (64bit)(ver.1803)(他PC)にインストールを行いました。
インストールは問題なく動作し、32bit用ドライバは %windir%\syswow64 フォルダ内に格納されています。

その後、手動でドライバのレジストリ登録を行うべく、
%windir%\syswow64\cmd を「管理者として実行」で起動し、
regsvr32 xxxxx.dll
を実行。問題なく完了します。
しかし、次に
regsvr32 xxxxx.ocx
を実行すると
「モジュール xxxxx.ocx は読み込まれましたが、DllRegisterServer への呼び出しは
エラーコード 0x800040200 により失敗しました。
この問題の詳細については、エラーコードを検索語として入力してオンラインで検索してください。」
とエラーが発生してしまいます。

このエラーコードでNET検索を行っても、解決策は「管理者として実行する」というものばかりで
本件の解決方法が見つかりません。

本現象の解決策をご存知の方がいらっしゃいましたら、ご教授をお願い致します。

また、インストール時に直接レジストリ登録する方法もあるのであれば、ご教授いただきたいです。

宜しくお願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+3

自分だったらこう調べるという方針を記載します。

DllRegisterServerの実装を行っている(もしくはATLなどで自動で生成されてた)ソースが
あるはずなのでそれを見つける。

HRSEULT WINAPI DllRegisterServer(){
    ::DebugBreak();
    //後続の処理
}


こんな感じでDebugBreakをしかける。

Windbgを管理者権限で起動する。
メニューの[Open Executable]からregsvr32を問題のocxを引数に指定して起動する。
仕掛けておいたDebugBreakで停止するのであとはステップ実行して調べる。

Windbgの使い方が分からない場合はC++でDllRegisterServerを実行するEXEを作成してVisual Studioなどでデバッグする。


確認するポイントの追記

タイプライブラリは.idlから生成されます。
生成された.tlbファイルは.rcファイル内で
1 TYPELIB "MFCActiveXControl1.tlb"
のような命令でリソースIDが1として埋め込まれます。

まずは.idlファイルがなければプロジェクトに追加します。
これはもともとのvc6.0のプロジェクト内にあったはずです。
プロパティでファイルの種類がidlになっていることを確認します。
イメージ説明

次にプロジェクトのプロパティでMIDLの設定を見ます。
タイプライブラリが生成する設定になっていることを確認します。
イメージ説明

リソースファイルのプロパティでファイルの種類を確認します。
イメージ説明

もともとrcファイルに TYPELIBを埋め込む命令が書いてあって
.tlbファイルがない場合リソースコンパイラでエラーになるはずです。
ですので、.rcファイルも怪しい気がします。
.rcファイルをコードの表示で直接開きます。(もしくはメモ帳などで直接開く)

//最初のほうに以下のようなブロックがあります。
//これは[リソースファイルのインクルード]の[コンパイル時に追加するファイル]
//の内容が登録されます。
3 TEXTINCLUDE 
BEGIN
    "1 TYPELIB ""MFCActiveXControl1.tlb""\r\n"
    "\0"
END

//終わりのほうに以下のようなインクルードの内容が展開された内容があります。
//こちらが実際にリソースコンパイラによって処理される命令です。
//これはリソースファイルをGUIから変更すると3 TEXTINCLUDE
//の内容をもとに自動生成されます。
//これが存在しないような気がします。

#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
1 TYPELIB "MFCActiveXControl1a.tlb"

/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED

一度ActiveXを作成するプロジェクトを作成して
自動で生成されるファイルや設定を見比べてみるといいと思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/08/10 15:21

    hmmm 様
    詳細な対応方法をご提示くださり誠に有難う御座います。

    ご指摘いただいた通り、.rc ファイルの最後の方の 1 TYPELIB "xxxxxx.tlb" 行が
    コメントアウトされていました。
    (.ocx 作成プロジェクトの移植時、この行で Error RC2135 が発生し、後々対応しようと
     コメントアウトしておいたのを忘れて放置したままとなっておりました。
     私のケアレスミスです。申し訳ございません。)

    また、.ocx のプロジェクトを見直したところ、 source files フォルダに .odl ファイルが
    すでに設定されていました。
    .odl ファイルのプロパティで、IDLファイルであることも確認できました。

    そこで、上記のコメントアウトを外し、ビルドし直しました(エラーは出ませんでした)。
    その後、インストールし、レジストリ登録を行ったところ、発生していたエラーは解消され
    問題なく登録できました。

    この度は、最後までご丁寧にご教授くださりまして誠に有難う御座いました。
    おかげ様で問題が無事解決できました。
    また、windowsについていろいろと勉強させていただきました。あわせて感謝致しております。
    また機会がありましたら、宜しくお願い致します。

    キャンセル

  • 2018/08/10 22:46

    解決できて何よりです。
    今回の話はCOMの話です。
    古すぎて絶版ですが、Essential COM(https://www.amazon.co.jp/dp/4756130666)がCOMの目的や実装方法が記載された本です。IDLについても触れられているので読んでみるといいかもしれません。
    アパートメントについてもっと知りたい(いまいち理解できない)場合は
    https://www.kekyo.net/2011/06/05/14
    がお勧めです。

    キャンセル

  • 2018/08/20 13:30

    hmmm 様
    ご返事が遅くなり、大変申し訳ありません。
    参考にすべき資料本とURLのご提示、誠に有難う御座います。
    ぜひ読んでみたいと思います。

    キャンセル

+3

そのOCXですが、32bit OSでは正しく登録できるのでしょうか?

また、自作のOCXではなく、Microsoftなどから配布されているOCXでやってみたらどうでしょうか?
(その場合も、SysWOW64で登録する必要があります。)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/08/06 16:13

    PineMatsu 様
    ご回答有難う御座います。

    exe ファイルと同一フォルダ内であれば使用可能なのですか?!
    恥ずかしながら知りませんでした。貴重な情報を有難う御座います。
    しかしながら、今回の .ocx / .dll は複数のアプリから使用される可能性があるため、レジストリ登録は行わなければなりません。

    キャンセル

  • 2018/08/08 16:54

    たしか、レジストリに登録しているのはDLLのパスを得るためです。レジストリになければ、順序は違っているかもしれませんが、EXEと同じディレクトリ、パスが通っているところを探しに行くはず。
    VB6では、ActiveXを登録せずにEXEと同じフォルダーに入れて使っていました。

    キャンセル

  • 2018/08/08 18:16

    PineMatsu 様
    ご回答有難う御座います。

    おっしゃる通り、今回の基となったVC++6.0で作成された.ocxと.dllは、VB6作成のインストーラ内でアプリと同一フォルダにパッケージング(.cab化)されて使われていました。
    ただし、格納場所は同一フォルダでしたが、$(DLLSelfRegister) と $(Shared) が付随していました。
    これはレジストリ登録のコマンドかと思っていました。
    (違っていましたら申し訳ありません。Windows開発の知識が全く足りていないということでご了承ください)

    キャンセル

+2

regsvr32はsyswow64フォルダにもあります。
32bitのocxを登録するにはこちらのregsvr32を使う必要があるかもしれません。
syswow64フォルダのcmdを実行してもsystem32フォルダがカレントとなり、syswow64フォルダのregsvr32が使われていない可能性があります。
フルパスで指定するか、カレントフォルダを移動してからregsvr32を実行してみてはいかがでしょうか。
的外れでしたらすみません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/31 17:01

    ttyp03 様
    ご回答有難う御座います。

    cmd起動直後のカレントフォルダ %windir%\system32 にて
    %windir%\syswow64\regsvr32 %windir%\syswow64\xxxxx.ocx
    も試してみましたが、現象は変わりませんでした。

    また、カレントフォルダを %windir%\syswow64 に移動して
    regsvr32 xxxxx.ocx
    も試してみましたが、現象は変わりませんでした。

    キャンセル

+1

以下のサイトに、同様の問題があったが、再度管理者権限でコマンドプロンプトを起動してうまくいった、という報告があります。

https://blogs.msdn.microsoft.com/rajakedar_ganta/2012/06/06/dllregisterserver-failed-with-the-error-code-0x80040201/

もう一度コマンドプロンプトを管理者権限で起動し、ocxの登録を行うとどうでしょうか?
お役に立てなかったらゴメンナサイ。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/31 16:39

    kenshirou 様
    ご回答有難う御座います。

    残念ながら、何度試しても現象は変わりませんでした。
    ※ /u 付きのコマンド(登録解除)は成功するんですが。。。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • C++に関する質問
  • 管理者で実行しているのに「モジュール xxxxx.ocx は読み込まれましたが、DllRegisterServer への呼び出しはエラーコード 0x800040200 により失敗しました。」が発生する