• ベストアンサー

CreateProcessについて

VC++6.0を使用し、NT上で以下のようなプログラムを作成していました。 Prcess_sts = ::CreateProcess(***_FULLPATH, NULL, NULL, NULL, FALSE, 0, NULL, ***_DIR, &pscinfo, &lpProcessInfo ); ***は起動する実行形名称です。作成したプログラムをNT上で動作させるには全く問題なかったのですが、OSがXPに変わった途端、この命令でアプリケーションの起動ができなくなりました。具体的な症状は、 ・カーソルは砂時計を表示し、フリーズしている ・タスクマネージャの『プロセス』を確認すると、99%がアイドル状態で、起動したアプリ及びCallしたアプリがリソースを食い潰している状態ではない。 という変な現象が発生しています。ちなみに、このような状態になるのは、コールしたプログラムの先でシリアル通信を行うものに頻発しているように感じます(気のせいかも?)また、全く問題なく起動することもあります。これはOSのせいなのでしょうか?もちろん、NT上で動作させていたときは全くなかった現象です。VC++がXPに対応していないからなのでしょうか?全く分からずに困っています。その道に明るい方がいましたら、ご教示ください。 PS マイクロソフトが発表している『32ビットプロセスでCreateProcess関数を呼び出しても正しく起動されない』というものとは違うようです。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • xcrOSgS2wY
  • ベストアンサー率50% (1006/1985)
回答No.2

補足ありがとうございます。なるほど、他社の実行プログラムですか・・・それはやっかいですね。 私ならばこういうところをチェックする・・・というところを挙げてみます。現象の発生頻度が分からないので的外れなところもあるかもしれません。 1. 念のため、タスクマネージャは常に「他社の実行プログラム」がプロセス一覧に表示される状態にしておく。もしかしたら何らかの原因で多重起動しており、多重起動が障害を引き起こしているのかもしれない。 2. CreateProcess()を実行した後、どこで止まっているのかを把握。あまり期待はできないが、CreateProcess()から「止まっているコード」までの間で何かヒントがあるかもしれない。(補足の文章の感じですとWaitForSingleObject()で他社プログラムの終了待ちで止まっているのかなという感じなのですが。) 3. CreateProcess()の直前に「CreateProcess()の場所に来たぞ」という意味のMessasgeBoxを表示し、「MessageBoxを閉じる」人手を介してCreateProcess()を実行する。こうすることで現象発生の頻度が下がるかどうかを確認。頻度が下がるとすればタイミング問題である可能性が高い。 4. CreateProcess()の直前に「CreateProcess()の場所に来たぞ」という意味のMessasgeBoxを表示し、CreateProcess()自体はコメントアウトしてしまう。MessageBoxによる表示が現れたら、その都度手作業で他社プログラムを起動し、それからMessageBoxを閉じる。(もしプロセスIDが必要であれば、その入力ルーチンも追加する必要があります。)こうすることで現象発生の頻度が下がるとすれば、CreateProcess()の実行自体に何らかの問題(パラメータが不適切等)がある可能性が高い。 5. 同上。ただし、他社プログラム起動時にWindows XPの「互換性機能」でWindows NT 4互換設定を使用してみる。何か変化があれば、「他社プログラム」自体がWindowsのバージョン番号に依存している可能性大。 6. 停止している(ように見える)他社プログラムのプロセス自体をデバッガにかけてスタックトレースを見る(ソースはないのでコードダンプを見てもしょうがない:どうしても必要になれば見ざるを得ませんが)。何度やっても違うアドレスでブレークするようであれば目に見えないだけでいちおう何らかの動作はしているし、毎回必ずWaitForXxxObjectの類でブレークするようであれば何かオブジェクト待ちになっていること「だけ」は分かる。 7. 「CreateProcess()による他社プログラムの実行とWaitForSingleObject()を繰り返すだけ」のような単純なサンプルプログラムを作成し、同様の現象が発生するかどうか確認する。このサンプルプログラムは、現象発生の頻度が高いほど、また内容がシンプルであればあるほど望ましい。ある程度の再現性が得られたら、再現性がなくなるまでプログラムをさらに単純化していく。単純化の過程で削った部分に原因のヒントがあるはず。 8. SysInternalsのHandleユーティリティ(http://www.sysinternals.com/utilities/handle.html)、Process Explorer (http://www.sysinternals.com/Utilities/ProcessExplorer.html)、MicrosoftのOpen Handles (http://www.microsoft.com/windows2000/techinfo/reskit/tools/existing/oh-o.asp)等を使って、他社プログラムがどのようなハンドルを開いているかを確認する。ひょっとしたらヒントになるかも。 うーん、あと何がありますかね・・・

guchi55
質問者

補足

ありがとうございます。 気になっているのは、NT上で動作させていたときは全く問題なく動作していたのに、XPに換えたとたん発生しているという点です。95系からXPであればなんとなく想像はつくのですが、この点がなんとも納得のいかないところです。とりあえず、明日、教えていただいたことを試してみます。ありがとうございます。

その他の回答 (2)

  • terra5
  • ベストアンサー率34% (574/1662)
回答No.3

CreateProcessの問題のように書かれてますが、NTで実行していた、おそらくNT4.0用のバイナリをそのままXPに持ってきて動かないという話の方が現実的にありそうな気がします。 DLLなんかも大分いれかわっているはずですし。 2000とXPならかなり差は少ないと思いますが、NT 4.0から2000への変更がかなり大きいと思います。 ですのでXPで安定して動かないというのはありそうな気がしますが。 直接実行させることも可能なら、それでXPで正常に動作するかをまず確認した方がいいと思います。 CreateProcessに問題があるとはちょっと考えづらいです。 あと、VC6.0はちゃんとSPあててますよね? 2000で使うにもアップデートしてないと問題が出るところがあります。

  • xcrOSgS2wY
  • ベストアンサー率50% (1006/1985)
回答No.1

以下の内容について補足願います。(いずれも、タスクマネージャとデバッガを使えばすぐに分かる事項かと思います。) 1. CreateProcessは実行を終了しているか。 2. CreateProcessでプロセスは作成されているか。 3. CreateProcessを実行したプロセス(スレッド)は、CreateProcess実行後も正常に動作しているか。 4. CreateProcessで作成したプロセスのmainないしWinMainは実行開始しているのか。 5. 「CreateProcessで指定している実行プログラム」は、単独で実行した場合は予期したとおり動作するのか。

guchi55
質問者

補足

ご指摘ありがとうございます。 1について   実行を終了しています 2について   プロセスは作成されています 3について   実行したプロセスは正常動作していません。Call  したプロセス(画面)の後ろに隠れている状態   ですが、タスクマネージャーを見ると立ち上がっ  ています。が、リソース使用はゼロです。 4について   他社のexeを起動しているので不明です 5について   単独で動作させると、通常通り(予期した)動作   します。 それと、今テストをしてみて分かってきたことなのですが、CreateProcessを2回使うとNGになることが多いようです。ちなみに CreateProcess() ⇒実行プログラムA WaitForSingleObject() Sleep(100) CreateProcess() ⇒実行プログラムB WaitForSingleObject() ここで実行プログラムBがメイン画面の後ろに隠れてしまう状態です(タスクマネージャで見るといるのですが、CPU使用ゼロで眠っているような感じです) また、毎回発生するわけではなく、立ち上がったり、たちあがらなかったりという感じです。調子がよいと必ず正常に起動してくれるのですが・・・ よろしくお願いします。

関連するQ&A

  • CreateProcessから制御が戻らない

    環境は Windows2000 Borland C++BuilderXです。 -------------------------------------------------------------------------------- fSuccess = CreateProcess( NULL, cmd_buf, NULL, NULL, FALSE, CREATE_NEW_PROCESS_GROUP | CREATE_NO_WINDOW | NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi ); -------------------------------------------------------------------------------- 上記のように子プロセスの起動を行っている箇所があるのですが 子プロセスが立ち上がらず、CreateProcessの呼び出しから制御が 戻らないことがあります。 この現象は毎回発生するわけではなく、再現性は低いのですが 同様の現象の前例などご存知の方がいらっしゃいましたら教えてください。 よろしくお願いします。

  • CreateProcess関数について

    ■CreateProcess関数で実行フアイル(.exe)を呼ぶプログラムを作成しています。 ■CreateProcess関数はプロセスを作成すると直に呼出側に戻って来るが、起動したプログラムの実行結果ではない。 ■その様な事を踏まえてプログラム下記にコーテイングしました(概要) ■「呼び出し側」も「呼び出される」もCD-ROM内に有ります。 ■問題はCreateProcess関数で呼んでから、実際に画像が表示されるまでに、時間が掛かる事です。、 ■「質 問」「やりたい事」 CreateProcess関数で呼んでから、実行画面が表示される時間の間に 「その旨のなんだかのメッセージを表示したい」 例えば、Webでのダウンロードやインストールの時の様な... この様な事を、実現するのはどの様にしますか、宜しくお願いします。 STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si,sizeof(si)); si.cb=sizeof(si); ZeroMemory(&pi,sizeof(pi)); if(CreateProcess(NULL,(LPTSTR)cmdline,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)){ CloseHandle(pi.hThread); //CD-ROMから直ぐ表示出来ない場合に備えて //この間で表示に時間を要している事をメッセージ出来ないか? ShowWindow(hWnd,SW_MINIMIZE);//タスクトレイに入れる。 WaitForSingleObject(pi.hProcess,INFINITE); CloseHandle(pi.hProcess); ShowWindow(hWnd,SW_RESTORE););//タスクトレイから出す。 }

  • createprocessで起動させる別.exeをモーダルで起動したい

    createprocessで起動させる別.exeをモーダルで起動したい お世話になります。 VC++6.0 MFCで開発しております。 現在A.exeのあるボタンを押すとcreateprocessでB.exeを起動させるようにしております。 B.exeを起動後、A.exeの画面表示をクリックするとA.exeがアクティブになるのです。 それを、B.exeが終了しないとA.exeがアクティブにならないように変更したいのですがどのようにすればよいでしょうか? 現状は PROCESS_INFORMATION pi; STARTUPINFO si; si.cb=sizeof(si); CreateProcess(実行EXEパス,コマンドライン,NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi); で起動しております。 また、実現不可能というお答えでもいいので教えていただければと思います。 お手数ですが何卒よろしくお願いします。

  • CreateProcessでwordのプロセスが複数出来ない

    開発環境:VC++2008 / Windows XP / Office2007 指定したOfficeファイルを、プログラムからアプリを指定して開き、 そのファイルが閉じられたら、次の処理を行うというプログラムを 作成中なのですが、 FindExecutableでアプリを検索し、 CreateProcessでアプリを起動。 WaitForSingleObjectで閉じられるまで待機し、 閉じられたら、次処理へ。という流れを マルチスレッドで行っています。 1つ目のwordファイル(a.doc)を開き、 2つ目のwordファイル(b.doc)を開くと、b.docの方は、 WaitForSingleObjectで待機せず、そのまま 次処理へ移行してしまいます。 CreateProcessの戻り値は正常で、b.docファイルも起動するのですが、 プロセス自体は、タスクマネージャで見る限り、1つしかありません。 word.exeが単一プロセスで複数ファイルをコントロールしていると思うのですが、 別プロセスで複数のwordを立ち上げる事は可能なのでしょうか?

  • CreateProcess error=0

    CreateProcessについて教えてください。 「program Files」配下にあるEXEを起動したいのですが、返却値が「0」で返却され、EXEが起動できません。ちなみに、「program Files」以外(スペースがない名称)の場合は、返却値「0以外」が返却され正常にEXEが起動できます。 また、VS2005で作成版では失敗し、VS6.0では成功します。(program Filesの場合) 原因がまったく、分からず困っています。どなたかご教示下さい。 CreateProcess(NULL,c:\program Files\AAA\AAA.exe,NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,c:\,c:\program Files\AAA,&si,&pi)

  • CreateProcessでの実行ファイルの操作について

    VC++ 6.0 Win98 カレントディレクトリに実行ファイルをいれておいて、szCommand[]="eee"とすると(eeeは実行ファイルです。)実行してくれるのですが、相対パスや絶対パスを使うと実行をしてくれません。 CreateProcessでは、相対パスや絶対パスは使えないのでしょうか? ちなみにコマンドラインから直接(相対パスや絶対パスを使用して)に打つと実行ファイルが動作します。 あと、リダイレクトも使えないのでしょうか?(動作しなかったので・・) STARTUPINFO si; ZeroMemory(&si,sizeof(STARTUPINFO)); si.cb=sizeof(STARTUPINFO); si.dwFlags=STARTF_USESTDHANDLES; si.hStdOutput=hFile; si.hStdError=hFile; char szCommand[]= "C:\\\"My Documents\"\\nannka\\VC++\\Ten3\\eee"; PROCESS_INFORMATION pi; CreateProcess( NULL, szCommand,//コマンド //NULL, NULL,NULL, TRUE, 0, NULL,NULL, &si,&pi ); よろしくお願いします。

  • アプリケーション起動について

    ひろと申します。 クライアントからサーバの共有フォルダにある、他のアプリケーションを オプション付きで起動させるプログラムをVC++で作成したのですが、 クライアントがNTだとうまくいきません。 たとえば、サーバ上にあるapp.exeを「app.exe /i」のような感じで 起動すると、クライアントがwin98の場合はアプリケーションが 表示されるのですが、NTから起動させようとすると、 アプリケーションは表示されません。 また、オプションを外すとアプリケーションは NTでも表示されます。 APIは、WinExec,ShellExecuteEx,CreateProcessで試したのですが 同じ結果でした。 CreateProcess は以下のように設定してます。 ------------------------------------------------------------------ STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(STARTUPINFO)); ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); si.cb = sizeof(STARTUPINFO); si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_SHOWNORMAL; CreateProcess(NULL, "serverpath\\app.exe /i", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); プロセスの起動は成功していうようです。 クライアントがNTの場合、他に必要な設定があるのでしょうか? よろしくお願いします。

  • CreateProcessでアプリが終了しない

    ちょっとした変換ツールを作ろうと思い、ダイアログベースの MFCアプリケーションを作成しました。 OKボタンが押された時にCreateProcess()で子プロセスを 起動して、終了したら結果表示して親プロセスも終了する 様にしようと思ったのですが、結果表示までは正常に 実行されるのですが、親プロセスが終了しません。 恐らくCreateProcess()に渡す引数が悪いのだと思うのですが、 どなたかわかる方がいらしたらご教示願います。 void CMscGenSelectorDlg::OnBnClickedOk() {   STARTUPINFO si;   PROCESS_INFORMATION pi;   ZeroMemory( &si, sizeof si );   si.cb = sizeof si;   ZeroMemory( &pi, sizeof pi );   // 子プロセス起動   CreateProcess(     NULL,                // モジュール名     _T("mscgen.exe -Tpng hoge.msc"),  // コマンドライン     NULL,                // セキュリティ記述子     NULL,                // セキュリティ記述子     FALSE,               // ハンドルの継承オプション     0,                 // 作成のフラグ     NULL,                // 新しい環境ブロック     NULL,                // カレントディレクトリ名     &si,                // スタートアップ情報     &pi);                // プロセス情報   // 子プロセス終了待ち   WaitForSingleObject( pi.hProcess, INFINITE );   CloseHandle( pi.hProcess );   CloseHandle( pi.hThread );   // シーケンスチャート表示   ShellExecute( NULL, _T("open"), _T("hoge.png"), NULL, NULL, SW_SHOW );   // 終了   OnOK(); }

  • CreateProcessでの環境変数の設定の仕方

    PATHを設定してCommand.comを実行したいのですが、 CreateProcessでの環境変数の設定の仕方がわかりません char* env = "PATH=c:\\data"; CreateProcess(NULL,"command.com /k path ", NULL, NULL, FALSE, 0, env, NULL, &si, &pi); このようにしてみたところDos窓が起動しますが、 表示されるPATHはデフォルトのままです。 環境は VC++6.0 MFC です。 どうか宜しくお願いします。

  • CreateProcessでコンソールアプリケーションを起動するには

    コンソールアプリケーションの中で、CreateProcess関数を用いて、自分自身のアプリケーションを起動したところ、次の結果になりました。 ・CreateProcess関数自体は成功する ・タスクマネージャで確認すると自分自身が2つ起動されている ただし、コンソールアプリケーションのウィンドウは1つしか開かず、そのウィンドウを2つのアプリケーションで共有しているかのように動作します(printfによるメッセージが2重に表示されるなど)。 使用言語はVC++ .NET 2008で、デバッガによる動作をさせています。 詳しい方、宜しくお願いします。