0

私はShellExecuteEx外部アプリケーションを実行するために使用しています:

SHELLEXECUTEINFO shExInfo = { 0 };
    shExInfo.cbSize = sizeof(shExInfo);
    shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
    shExInfo.hwnd = 0;
    shExInfo.lpVerb = L"runas";                // Operation to perform
    shExInfo.lpFile = windowStringContainingAppPath.c_str();       // Application to start    
    shExInfo.lpParameters = windowStringContainingAppParameters.c_str();                  // Additional parameters
    shExInfo.lpDirectory = 0;
    shExInfo.nShow = SW_SHOW;
    shExInfo.hInstApp = 0;

    if(ShellExecuteEx(&shExInfo))
    {
        WaitForSingleObject(shExInfo.hProcess, INFINITE);

        DeleteFile(wsMesh3dx64Parameter.c_str());

        CloseHandle(shExInfo.hProcess);
    }

すべてが完全に機能しますが、メイン ウィンドウを閉じた後もプロセスがまだアクティブであるという、この外部アプリの予期しない動作が存在します。これによりWaitForSingleObject(shExInfo.hProcess, INFINITE);、戻ることができなくなり、手動でプロセスを終了する必要があります。

WaitForSingleObject(shExInfo.hProcess, INFINITE);代わりに、外部プロセスがウィンドウを所有しているかどうかをチェックし、そうでない場合はそれを終了するループに置き換える方法を探しています。

これは私が考えたものですが、より良い方法があれば指摘してください。

アップデート:

ロブソンの回答のおかげで、私は意図したことを何とかすることができました:

struct Porcess_ID_HWND
{
    DWORD processID;
    HWND processhWnd;
};

BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
    Porcess_ID_HWND*info = (Porcess_ID_HWND*)lParam;

    DWORD processID;
    GetWindowThreadProcessId(hWnd, &processID);

    if (processID == info->processID){
        info->processhWnd = hWnd;
        return FALSE;
    }

    return TRUE;
}

そして私のループ:

if(ShellExecuteEx(&shExInfo))
{
    DWORD dwProcessID = GetProcessId(shExInfo.hProcess);

    Porcess_ID_HWND info;
    info.processID = dwProcessID;
    // wait for window to appear
    do
    {
        info.processhWnd = NULL;
        EnumWindows(EnumWindowsProc, (LPARAM)&info);

    } while (!info.processhWnd);

    // wait for window to close
    do
    {
        info.processhWnd = NULL;
        EnumWindows(EnumWindowsProc, (LPARAM)&info);

    } while (info.processhWnd);

    //WaitForSingleObject(shExInfo.hProcess, INFINITE);

    DeleteFile(wsMesh3dx64Parameter.c_str());

    CloseHandle(shExInfo.hProcess);
}
4

1 に答える 1

3

http://forums.codeguru.com/showthread.php?392273-RESOLVED-How-to-get-window-s-HWND-from-it-s-process-handleで良い答えを見つけました

1)
HAVE: プロセス ID、NEED: プロセス ハンドル
解決策: OpenProcess()

2)
HAVE: プロセス ハンドル、NEED: プロセス ID
解決策: GetProcessId()

3)
HAVE: ウィンドウハンドル、NEED: プロセス ID
解決策: GetWindowThreadProcessId()

4)
HAVE: ウィンドウハンドル、NEED: プロセスハンドル
解決策: 3) を使用してから 1) を使用します。

5)
HAVE: プロセス ID、NEED: ウィンドウハンドル
解決策: EnumWindows()、コールバック関数で 3) を実行し、プロセス ID と一致するかどうかを確認します。

6)
HAVE: プロセス ハンドル、NEED: ウィンドウ ハンドル
解決策: 2) そして 5)

したがって、ケース 6 です。ウィンドウ ハンドルのプロセス ID が shExInfo.hProcess のプロセス ID と一致しない場合、shExInfo.hProcess はウィンドウを所有していません。

于 2015-05-05T11:28:49.277 に答える