(C/C++)Windows APIのCreateProcessWithLogonW関数を使うとEXEが落ちる
(C++)別ユーザでプロセスを起動するにて、Windows API の CreateProcessWithLogonW 関数を使うことで別ユーザ権限でプロセスを起動できることを書きました。
で、このコードをコンソールアプリケーションとしてビルドしテストしたところ、特定のマシンだけ動かないという現象が起きたのです。(Visual C++ 2008 Express にて、Win32 としてビルド)
exeを起動した瞬間にコマンドプロンプト画面は表示されるものの一瞬で消えるという現象です。試しに、コードの最初の方に MessageBox も入れてみましたが、それも表示されません。どうやらexe起動時にほんとに落ちてるようです。
この現象が起きるのが Windows Server 2003 x64 版で5台のサーバのうち3台で発生します。
Windows Server 2003 の x86 環境ではおきません。
試しに Win32 コンソールアプリで、printf だけ使ったexeを動かしたところ、それは問題なく動きます。
ダメになるのは、CreateProcessWithLogonW 関数をコードの含めたときです。
MSサポート:32 ビット プロセスで CreateProcess 関数を呼び出しても別の 32 ビット プロセスが正しく起動されないによると、32bitアプリから、CreateProcess系の関数を動かすと、メモリリークのため開始できないとあります。
しかし、メモリリークしてる感じはないんですよね。exe立ち上げ瞬間落ちてますから。。
で、VC++のプロジェクト構成をいろいろ触っているうちに、構成プロパティ → C/C++ → 最適化 → 最適化 の値を変更することで動かなかった環境でも動くようになりました。
デフォルトで「最適化」の値が「実行速度 (/O2)」になってたんですが、これを「無効 (/Od)」もしくは「プログラム サイズ (/O1)」にすると動作するようになりました。
MSDN:リリース ビルド作成時によくある問題、MSDN:コードの最適化によると、最適化によりまれに予期しないコードを生成し問題を引き起こすということが書かれてました。
結局詳細な原因がわからなかったのはモヤモヤしますが、最適化の設定の変更で動くようになったので、助かりました。
しかし、やはり C++ は難しいですね。