2017-06-12 2 views
2

私は、Windowsエクスプローラの4つのインスタンスを開き、PinvokeのMoveWindowを使用して画面に配置する単純なC#コンソールアプリケーションを作成しています。私の問題は、Process.Startコマンドがあまりにも遅く実行されているように見え、MoveWindow関数が意図的にプログラムを遅くしない限り、そのプロセスを見つけることができないということです。ここに私のコードは次のとおりです。Process.Startが完了するまで次の行を実行しない

Process.Start(new ProcessStartInfo() 
{ 
    FileName = "explorer", 
    Arguments = location, //Defined elsewhere (for testing just ".") 
    UseShellExecute = false 
}); 
int[] pos = GetPositions(position); //Little function which gets the positions I want for this window 
System.Threading.Thread.Sleep(500); 
IntPtr hnd = GetForegroundWindow(); 
bool ok = MoveWindow(hnd, pos[0], pos[1], pos[2], pos[3], false); 

は、私は(任意)半秒間Sleepに抱えている方法を参照してください。私はそれが実行されるマシンの仕様を知らないので、理想的ではありません。それは、高速機では効率が悪くなるか、遅い機種では破損する可能性があります。私が任意に設定された時間待つ必要がないプロセスが始まるまで、より具体的な方法を待っていますか?


はまた、半関連ノートで、あなただけの私が移動したいウィンドウをつかむために前面のウィンドウを取得カウボーイコードのビットに気づくことがあります。これは、特定のWindow Explorerプロセスを選別しようとしているためです。私が言うことは、メモ帳やIEでテストしていたときと同じように動作せず、ハンドルを渡すだけではうまく動作しないということです。この問題に精通している人は誰でも自由に寄付することができますが、それに時間を費やさなければ、この解決策は不格好です。それはうまく機能しますが、少しでも時間をかけて頭を叩きたくないキーボードはそれを行う正しい方法を理解しようとしています。

答えて

0

あなたは理論的には、この

while(!process.HasExited) 
{ 
    //process running 
} 
//Done 
+0

問題は、何らかの理由でプロセスが開始され、Windowsエクスプローラウィンドウが別々に表示されることです。その場合、ハンドルを見つけることができませんでした。いずれにしても、私は何かしたくないです。*プロセスが終了するまでは、ビジュアルディスプレイがロードされた後に何かをしたいだけです。Windowsエクスプローラでプロセス自体とは異なるタイムテーブルで実行されるようです。 –

2

ような何かを試すことができ、あなたがメッセージループが作成され、稼働して新たに起動されたプロセスであることされるのを待つProcess.WaitForInputIdle()を呼び出すことができるでしょう。ただし、これはすべてのアプリケーションで機能するわけではありません(Windowsエクスプローラではない可能性があります)。

安いトリックを作成するプロセスのメインウィンドウ(source)をポーリングすることです:

public static bool WaitForMainWindow(this Process process) 
{ 
    while (!process.HasExited && process.MainWindowHandle == IntPtr.Zero) 
    { 
     Thread.Sleep(10); 
    } 

    return !process.HasExited; 
} 

あなたはタイムアウトを追加することで、これはより堅牢にする場合があります

public static bool WaitForMainWindow(this Process process, uint timeout) 
{ 
    var start = DateTime.Now; 
    while (!process.HasExited && process.MainWindowHandle == IntPtr.Zero) 
    { 
     Thread.Sleep(10); 
     if ((DateTime.Now - start).TotalMilliseconds >= timeout) 
     { 
      return false; 
     } 
    } 

    return !process.HasExited; 
} 
+0

これを試してみると、常にfalseが返されます。 '' 'MainWindowHandle'''は常にゼロです(私が知る限り) –

関連する問題