web-dev-qa-db-ja.com

C#Process.MainWindowHandleは常にIntPtrゼロを返します

これは私のコードです:

            using (Process game = Process.Start(new ProcessStartInfo() { 
        FileName="DatabaseCheck.exe",
        RedirectStandardOutput = true,
        CreateNoWindow = true,
        UseShellExecute = false }))
        {
            lblLoad.Text = "Loading";
            int Switch = 0;

            while (game.MainWindowHandle == IntPtr.Zero)
            {
                Switch++;
                if (Switch % 1000 == 0)
                {
                    lblLoad.Text += ".";
                    if (lblLoad.Text.Contains("...."))
                        lblLoad.Text = "Loading.";

                    lblLoad.Update();
                    game.Refresh();
                }
            }

問題は、そのgame.MainWindowHandleが常にIntPtr.Zeroであるということです。実行されたプロセスのIntPtrを見つけて、ゲームがランチャーによって開始されたことを確認する必要があるため、ゲームにIntPtrを送信させ、問題がなければランチャーに応答させました。しかし、そのためには、実行されたプロセスのIntPtrを具体的に知る必要があります。

前もって感謝します!

13
Kfirprods

メインウィンドウは、現在フォーカスがあるプロセスによって開かれたウィンドウです(トップレベルフォーム)。 Refreshメソッドを使用してProcessオブジェクトを更新する必要があります変更されている場合は現在のメインウィンドウハンドルを取得します

MainWindowHandleプロパティは、ローカルコンピューターで実行されているプロセスに対してのみ取得できます。 MainWindowHandleプロパティは、プロセスに関連付けられているウィンドウを一意に識別する値です。

プロセスにグラフィカルインターフェイスがある場合にのみ、プロセスにメインウィンドウが関連付けられます。関連するプロセスにメインウィンドウがない場合、MainWindowHandle値はゼロです。非表示になっているプロセス、つまりタスクバーに表示されていないプロセスの値もゼロです。これは、タスクバーの右端にある通知領域にアイコンとして表示されるプロセスの場合に当てはまります。

プロセスを開始したばかりで、そのメインウィンドウハンドルを使用する場合は、WaitForInputIdleメソッドを使用してプロセスの開始を終了し、メインウィンドウハンドルが作成されていることを確認することを検討してください。それ以外の場合は、例外がスローされます。

15
VS1

回避策は、すべてのトップレベルウィンドウを列挙し、一致するものが見つかるまでそれらのプロセスIDを調べることです...


    [DllImport("user32.dll")]
    public static extern IntPtr FindWindowEx(IntPtr parentWindow, IntPtr previousChildWindow, string windowClass, string windowTitle);

    [DllImport("user32.dll")]
    private static extern IntPtr GetWindowThreadProcessId(IntPtr window, out int process);

    private IntPtr[] GetProcessWindows(int process) {
        IntPtr[] apRet = (new IntPtr[256]);
        int iCount = 0;
        IntPtr pLast = IntPtr.Zero;
        do {
            pLast = FindWindowEx(IntPtr.Zero, pLast, null, null);
            int iProcess_;
            GetWindowThreadProcessId(pLast, out iProcess_);
            if(iProcess_ == process) apRet[iCount++] = pLast;
        } while(pLast != IntPtr.Zero);
        System.Array.Resize(ref apRet, iCount);
        return apRet;
    }
5
dynamichael
while (!proc.HasExited)
{
    proc.Refresh();
    if (proc.MainWindowHandle.ToInt32() != 0)
    {
        return proc.MainWindowHandle;
    }
}
4
ounami