2012-11-16 3 views
5

this codeに似たCreateProcessAsUser()APIを使用して、サービスからユーザーモードプロセスを開始しようとしています。私のコードは99%の時間で正常に動作しますが、APIが成功する時を除いて、私はPROCESS_INFORMATION構造体からプロセスハンドルを取得しますが、プロセス自身は実行しようとしていたインタラクティブなユーザーセッションには表示されません。CreateProcessは成功しましたが、GetExitCodeProcessはC0000142を返します。

興味深いのは、プロセスハンドルでGetExitCodeProcess()を呼び出すと、戻りコード0xC0000142で成功するということです。どんな考え?

+0

障害が発生すると、子プロセスを開始できますか?実行しようとしている.exeが、欠落しているDLLに依存する可能性はありますか? –

+1

リターンコードは動作に確実に適合し、STATUS_DLL_INIT_FAILEDです。これは確かにプロセスの開始を妨げるでしょう。使用するDLLの1つは、そのDllMain()エントリポイントからFALSEを返します。あなたはそれをデバッグできるように、あなたのdevマシン上でこれをreproする必要があります。 –

+0

@HansPassantとMichaelShアドバイスをありがとう。そのユーザーセッションにログインし、手動でプロセスを開始できるかどうかを確認する必要があります。問題はそれが常に発生しないということです...しかし、私が持っている質問は、明らかに何も開始しないときにCreateProcessAsUser()がTRUEを返すのはなぜですか? – ahmd0

答えて

6

エラー0xC0000142がSTATUS_DLL_INIT_FAILED(これはError Code Lookup Toolを使用して決定しました)です。この問題の

最も一般的な原因はuser32.dllにリンクするプログラムは、システムのウィンドウステーションとデスクトップに話すことができませんでしたコンテキストで実行されたことがある:簡単にGoogleは述べていた、this questionを発見しました。通常、エージェントなどのサービスは独自のウィンドウステーションとデスクトップで実行され、user32プログラムは正常に動作しますが、ダイアログボックスを表示したプログラムは、人間がエラーメッセージを表示したりダイアログを閉じたりする機会がなく。

したがって、user32.dllの機能を使用していない場合は、その依存関係を削除する必要があります。そのDLLを使用している場合は、私は本当にあなたが何をすべきかわからない。 1つの選択肢は、DLLを動的にLoadLibraryでロードし、成功した場合(つまり、有効なウィンドウセッションがある場合)、または失敗した場合に失敗モードでフォールバックすることです。

+0

ありがとう。私が試してみます。 user32.dllを使用しないのはちょっと難しいですが、わかっています...私のコードでは、ユーザーのコンテンツは表示されません。実行するだけで、グローバルな名前付きイベントが開き、イベントが設定され、エラーコードに結果が返されます。 – ahmd0

+0

低い整合性プロセスを実行したが、中程度の整合性(またはそれ以上)をサービスとして実行した場合は、このような何らかの理由が起こりますか? –

+0

エラーコードの検索ツールへのリンクのUpvoteは、最近ではエラーコードのためのグーグルが困っているためです。 –

5

CreateProcess ...()APIは、内部プロセスオブジェクトの作成に成功し、beginの初期化を行うとTRUEを返します。プロセスがロードされて実行可能イメージが実行されるのを待つことはありません。場合によっては、後で初期化が失敗することもありますが、カーネルの観点からは依然としてプロセス作成に成功しています。

+0

良い点。ありがとう。では、私のプロセスが「確実に」開始されたことを知る正しい方法は何ですか? – ahmd0

+0

パイプや何かを介してプロセスと直接通信できない限り、CreateProcess()の後に少し待ってGetExitCodeProcess()を呼び出してSTILL_ACTIVE戻りコードをチェックするのが最善の方法だと思います。 – HerrJoebob

+0

また、 'WaitForInputIdle()'を使用してください。 –

関連する問題