4

プロセスが別のプロセスから終了したかどうかを確認する方法に関するいくつかの投稿を読み(ここでセマンティクスに夢中になっている人もいますが、ユーモアを交えて)、実装しようとしましたが、エラーコード5が発生しています。 ("ERROR_ACCESS_DENIED")いたるところに。

これが私がすることです。

1)プロセス1(P1)はプロセス2を起動し、共有メモリの場所に独自のPIDを書き込みます。

2)プロセス2(P2)は共有メモリからPIDを読み取ります

3)P2はP1のPIDを使用してOpenProcess(...)を呼び出し、後で確認できるハンドルを保存します。

4)P2はP1のPIDを使用してGetExitCodeProcess(...)を繰り返し呼び出し、STILL_ACTIVEコードをチェックします。

上記のメソッドでは、GetExitCodeProcessでACCESS_DENIEDエラーが発生し続けます。私はMSDNのドキュメントから以下のコードを使用してP2の特権を変更しようとしました:

HANDLE proc_h = OpenProcess(SYNCHRONIZE, FALSE, GetCurrentProcessId());
HANDLE hToken;
OpenProcessToken(proc_h, TOKEN_ADJUST_PRIVILEGES, &hToken);

LookupPrivilegeValue(NULL, lpszPrivilege, &luid );

tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
// Enable the privilege
AdjustTokenPrivileges(hToken, 
                      FALSE, 
                      &tp, 
                      sizeof(TOKEN_PRIVILEGES), 
                      (PTOKEN_PRIVILEGES) NULL, 
                      (PDWORD) NULL);

しかし、OpenProcessToken(...)メソッドの呼び出しでACCESS_DENIEDエラーが発生し続けます。それで、これはある種のシステムレベルのハードルを示していますか?私は自分のマシンの管理者権限を持っており、XPを実行しています。

助けてくれてありがとう。

4

3 に答える 3

4

GetExitCodeProcessに渡されるハンドルにはPROCESS_QUERY_INFORMATIONアクセス権が必要です。以下はうまくいきます:

int main(int a_argc, char** a_argv)
{
    int pid = atoi(*(a_argv + 1));

    HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);

    if (NULL != h)
    {
        Sleep(2000);
        DWORD exit_code;
        if (FALSE == GetExitCodeProcess(h, &exit_code))
        {
            std::cerr << "GetExitCodeProcess() failure: " <<
                GetLastError() << "\n";
        }
        else if (STILL_ACTIVE == exit_code)
        {
            std::cout << "Still running\n";
        }
        else
        {
            std::cout << "exit code=" << exit_code << "\n";
        }
    }
    else
    {
        std::cerr << "OpenProcess() failure: " << GetLastError() << "\n";
    }

    return 0;
}

GetExitCodeProcessハンドルを開いてポーリングする代わりに、SYNCHRONIZE終了するのを待ちます。

int main(int a_argc, char** a_argv)
{
    int pid = atoi(*(a_argv + 1));

    HANDLE h = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, FALSE, pid);

    if (NULL != h)
    {
        WaitForSingleObject(h, 5000); // Change to 'INFINITE' wait if req'd
        DWORD exit_code;
        if (FALSE == GetExitCodeProcess(h, &exit_code))
        {
            std::cerr << "GetExitCodeProcess() failure: " <<
                GetLastError() << "\n";
        }
        else if (STILL_ACTIVE == exit_code)
        {
            std::cout << "Still running\n";
        }
        else
        {
            std::cout << "exit code=" << exit_code << "\n";
        }
    }
    else
    {
        std::cerr << "OpenProcess() failure: " << GetLastError() << "\n";
    }

    return 0;
}
于 2012-01-17T16:43:38.547 に答える
1

P1 の終了時に P2 に何かをさせたい場合は、別の方法がおそらくかなり簡単です。P1 にパイプを作成させ、P2 にそのパイプへのハンドルを継承させます。P2 では、パイプからの読み取りを実行します。P2 の への呼び出しがReadFileのエラーで返された場合ERROR_BROKEN_PIPE、P1 は終了しています。

于 2012-01-17T16:41:50.217 に答える
1

OpenProcesstoken には、SYNCHRONIZE アクセスのみでプロセスを開く PROCESS_QUERY_INFORMATION が必要です。それが機能するかどうかを追加するかどうかを確認してください| PROCESS_QUERY_INFORMATION

于 2012-01-17T16:35:47.410 に答える