none
ATL(Windowsサービス)からMFCで作成したODBCクラスを用いたDBアクセスの方法 RRS feed

  • 質問

  • お疲れ様です。

    Visual Studio 2012/C++(ATL)のウィザードで作成したWindows7向けのWindowsサービスから、

    起動したスレッドからMFCで作成されたODBCのCRecordsetにデータベースにアクセスしようとしていますが、

    CRecordset::Open()メソッドの呼び出しで落ちてしまいます。

    これは、ATLからのMFCで作成したCRecordsetの使用を禁止しているのでしょうか??

    それとも、何か特別なことをやらないといけないのでしょうか??

    ご教授をお願いいたします。


    2013年10月22日 11:10

回答

  • 「落ちる」とは、「強制終了してしまう」のですよね?

    エラーでそのまま終了シーケンスが走る(または、起動に失敗したという処理で終わる)ということではありませんよね?

    そのサービスの問題の箇所(と思われる部分)をデバッグすることはできますか?サービスとしてデバッグ可能であれば、デバッガで原因を探ってみてください。

    もし、サービスとしてはデバッグできない場合は、通常プロセスとして実行させてデバッグしてみてください。

    ATLのサービスプロジェクトは、レジストリを見て自身を通常プロセスとして実行する仕組みを持っています。

    ATLのソースを確認してもらえばわかりますが、AppId キー(自分のモノ)にある、LocalService というレジストリ値の存在を確認して、サービスとして動かすかどうかを決めています。

    もし、通常プロセスとして起動させるのは問題がなく、サービスで動かすと強制終了するというのであれば、アクセス権の問題などが考えられますが、現時点では原因がわかりませんので、まずは原因を絞り込むところから始める必要があると思います。


    とっちゃん@わんくま同盟, Microsoft MVP for Visual C++(Oct 2005-) <a href="http://blogs.wankuma.com/tocchann/"> http://blogs.wankuma.com/tocchann/</a>

    2013年10月23日 7:08

すべての返信

  • theApp(CWinAppまたは派生クラスのインスタンス)がありませんよね?また、初期化処理も行われていないですよね?

    まずはここの部分を初期化しておかなければ、MFCのオブジェクトは使えません。

    MFCではないプロジェクト(その形式は問わない)からMFCのオブジェクトを呼び出したい場合は、そのプロジェクトをMFC化する(一部のC++プログラムのみ実現可能)か、レギュラーDLLにMFCオブジェクトをおしこめ、それを外部から呼び出す形をとるかのいずれかになります。

    MFCはその構造と歴史的な経緯により、サービスプロセスを作成することができません。ですので今回の場合は、レギュラーDLLの形をとるのがよいと思います。

    CRecordsetなどのデータベース系はAPIレベルも含め、触ったことがないので詳細はわかりませんが、もしメッセージ処理を行っている場合はUIスレッド(通常、ServiceMain(OnStartなどが呼ばれるスレッド)で利用する必要があるので注意してください。

    ※UIスレッドは、メッセージループ(CAtlServiceModuleT::RunModalLoop() の実装と同じようなもの)が動いているスレッドを指します。画面に何かを表示するものを指しているわけではないので誤解しないようにしてください。


    わんくま同盟,Microsoft MVP for Visual C++(Oct 2005-) http://blogs.wankuma.com/tocchann/

    2013年10月23日 1:47
  • わんくま同盟さま

    ご回答ありがとうございました。

    残念ながら、DLLに閉じ込める作戦でもサービスプロセスの挙動が同じものとなりました。

    HTTPアクセスなどは問題なく動作できているのに対し、データベースだけがダメなので、何か設定で漏れているものがあるのかもしれませんね。

    困りました・・・C#では問題なく可能みたいなのですけど。。。

    2013年10月23日 6:15
  • 「落ちる」とは、「強制終了してしまう」のですよね?

    エラーでそのまま終了シーケンスが走る(または、起動に失敗したという処理で終わる)ということではありませんよね?

    そのサービスの問題の箇所(と思われる部分)をデバッグすることはできますか?サービスとしてデバッグ可能であれば、デバッガで原因を探ってみてください。

    もし、サービスとしてはデバッグできない場合は、通常プロセスとして実行させてデバッグしてみてください。

    ATLのサービスプロジェクトは、レジストリを見て自身を通常プロセスとして実行する仕組みを持っています。

    ATLのソースを確認してもらえばわかりますが、AppId キー(自分のモノ)にある、LocalService というレジストリ値の存在を確認して、サービスとして動かすかどうかを決めています。

    もし、通常プロセスとして起動させるのは問題がなく、サービスで動かすと強制終了するというのであれば、アクセス権の問題などが考えられますが、現時点では原因がわかりませんので、まずは原因を絞り込むところから始める必要があると思います。


    とっちゃん@わんくま同盟, Microsoft MVP for Visual C++(Oct 2005-) <a href="http://blogs.wankuma.com/tocchann/"> http://blogs.wankuma.com/tocchann/</a>

    2013年10月23日 7:08
  • とっちゃん@わんくま同盟さま

    度々ありがとうございます。

    すべてが解決できました!!

    ODBCデータソースの参照先(ユーザー/システム)が原因でした。

    正しい参照先に変更したところ、正常に機能することが確認できました。

    原因に気づく「キッカケ」頂きありがとうございました。

    2013年10月23日 8:13