プロセス起動ができません

解決


ゴンタ  2010-02-02 05:57:05  No: 71344

お世話になります。

Visual Studio2005 VC++でダイアログベース
にてボタンを押したら別プロセスを起動するように
以下のコードを書いて実行したところCreateProcessにて
エラーが発生しました。
実行元のexeと実行先のexeはともに同じフォルダに存在します。
お手数ですが、お教え頂けないでしょうか?

int ret_code;
DWORD lpExitCode;
PROCESS_INFORMATION  pro_id;
STARTUPINFO  str_inf;

//-------------------------
//  pro_id構造体初期化
ZeroMemory( &pro_id , sizeof(PROCESS_INFORMATION)); 
//-------------------------
//  str_inf構造体初期化
ZeroMemory( &str_inf , sizeof(STARTUPINFO));
str_inf.cb          = sizeof(STARTUPINFO);
str_inf.dwFlags     = STARTF_USESHOWWINDOW;
str_inf.wShowWindow = SW_SHOWNORMAL;

//-------------------------
//  外部プロセスの実行
ret_code = CreateProcess( NULL, _T("BmpDisplaySample.exe"), NULL, NULL, FALSE, 0, NULL, NULL, &str_inf, &pro_id);

//--------------------------
//  プロセスの終了待ちループ
lpExitCode = STILL_ACTIVE;
while (lpExitCode == STILL_ACTIVE ) {
//  終了コードを取得
   GetExitCodeProcess( pro_id.hProcess , &lpExitCode ) ;
}
CloseHandle(pro_id.hProcess);


ゴンタ  2010-02-02 07:00:42  No: 71345

追記致します。
VC++6.0にてソースコード流用して
実行すると、
//  外部プロセスの実行
ret_code = CreateProcess( NULL, _T("BmpDisplaySample.exe"), NULL, NULL, FALSE, 0, NULL, NULL, &str_inf, &pro_id);

は正常に"BmpDisplaySample.exe"を起動できます。

VC++6.0とVS2005の設定等の違いが何かあるのでしょうか?


瀬戸っぷ  2010-02-02 07:13:13  No: 71346

>以下のコードを書いて実行したところCreateProcessにて
>エラーが発生しました。

GetLastError()はなんと言っていますか?

>実行元のexeと実行先のexeはともに同じフォルダに存在します。

カレントディレクトリはどこなんでしょう?

>VC++6.0とVS2005の設定等の違いが何かあるのでしょうか?

Win32API使う限り、それほど大きな差はないでしょう。
プロジェクトさせ居したときのデフォルトの文字コードがMBCSかUNICODEか…
という、ある意味で大きな違いはありますが。
# 最終的に呼び出されるAPIも微妙に変わる。

>//  プロセスの終了待ちループ
>lpExitCode = STILL_ACTIVE;
>while (lpExitCode == STILL_ACTIVE ) {
>//  終了コードを取得
>   GetExitCodeProcess( pro_id.hProcess , &lpExitCode ) ;
>}
>CloseHandle(pro_id.hProcess);

CPU使用率を叩き上げるコードですね。
WaitForSingleObject()等で待機するのが一般的かと思いますが…
起動したプロセスが終了コードとして0x00000103L(STILL_ACTIVE)を返却すると無限ループに…


tetrapod  2010-02-02 17:40:21  No: 71347

VC++6 と VS2005 ではプロジェクト(ソリューション)内ディレクトリ構成が変更されているし
統合デバッガからアプリケーション起動時のカレントディレクトリ位置も違うので
提示コードで動かないのは当然。

仕様次第だったりするが GetModuleFileName の結果を加工するなどして
フルパスでファイル名を指定するようにしておかなきゃだめ。
セキュリティ的脆弱性って奴になっちゃうぞ


aetos  2010-02-02 19:15:45  No: 71348

> プロジェクトさせ居したときのデフォルトの文字コードがMBCSかUNICODEか…
> という、ある意味で大きな違いはありますが。
> # 最終的に呼び出されるAPIも微妙に変わる。

まさにそれが原因ではないでしょうか。
関数プロトタイプをよく見てください。

http://msdn.microsoft.com/ja-jp/library/cc429066.aspx

第2引数は LPTSTR です。ここに文字列リテラルを渡してはいけません。
VC++6.0 では CreateProcessA が呼び出され、この関数は内部的にバッファを確保して MultiByteToWideChar で文字列を変換してから、それを CreateProcessW に渡します。
このとき、CreateProcessW の第2引数に渡されるのは書き換え可能な内部バッファなので動きます。
VC++2005 では直接 CreateProcessW にリテラルが渡されるので落ちます。


ゴンタ  2010-02-03 00:09:50  No: 71349

お世話になります。

> プロジェクトさせ居したときのデフォルトの文字コードがMBCSかUNICODEか…
> という、ある意味で大きな違いはありますが。
> # 最終的に呼び出されるAPIも微妙に変わる。

御回答有難う御座います。

プロジェクトのプロパティで
「文字セットでマルチバイト文字セットを使用する」
を選択した他プロセスを起動できました。
有難う御座いました。


Blue  2010-02-03 00:39:25  No: 71350

aetosさんのご指摘通り

TCHAR szExe[] = _T("BmpDisplaySample.exe");
ret_code = CreateProcess( NULL, szExe, NULL, NULL, FALSE, 0, NULL, NULL, &str_inf, &pro_id);

とするのはどうだったのでしょうか?

>「文字セットでマルチバイト文字セットを使用する」
>を選択し
は安易に変更してもよいのか見当も必要なのでは。
(マルチバイト文字セットだとUnicode文字セットよりあらわせる文字が少なくなる。)


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加