He leído un par de posts sobre cómo comprobar si ha terminado un proceso de un proceso distinto (me doy cuenta de que algunas personas se confunden sobre la semántica de aquí, pero sólo el humor me) y traté de ponerla en práctica, pero estoy postulando en el código de error 5 («ERROR_ACCESS_DENIED») en todo el lugar.

Aquí es lo que yo hago.

1) Proceso 1 (P1) lanza el proceso 2 y escribe de una memoria compartida, la ubicación de su propio PID.

2) Proceso 2 (P2) lee el PID de memoria compartida

3) P2 llamadas OpenProcess(…) con P1 PID para ahorrar un mango que se puede comprobar más tarde.

4) P2 llamadas GetExitCodeProcess(…) con P1 PID repetidamente y se comprueba para un STILL_ACTIVE código.

En el método anterior, sigo recibiendo el ACCESS_DENIED error en GetExitCodeProcess. He intentado modificar P2 privilegios mediante el siguiente código de MSDN docs:

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);

Pero sigo recibiendo el ACCESS_DENIED error en la llamada a la OpenProcessToken(…) el método. Así lo hace indicar algún tipo de sistema de nivel de obstáculo? Tengo derechos de administrador en mi máquina y me estoy quedando XP.

Gracias de antemano por cualquier ayuda.

  • Puede publicar su código que es el proceso de apertura de la manija para P1 P2? Estás especificando la PROCESS_QUERY_INFORMATION bandera en el desisredAccess parámetro para OpenPRocess?
  • hmjd adivinado el problema. Yo estaba usando la sincronización de los permisos y no PROCESS_QUERY_INFORMATION.
InformationsquelleAutor Ian | 2012-01-17

3 Comentarios

  1. 4

    El identificador pasado a GetExitCodeProcess requiere PROCESS_QUERY_INFORMATION derecho de acceso.
    El siguiente funciona bien:

    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;
    }

    Lugar de votación en GetExitCodeProcess abra el asa con SYNCHRONIZE y esperar a que salga:

    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;
    }
    • Muchas gracias, que funcionó bien.
  2. 1

    OpenProcesstoken requiere PROCESS_QUERY_INFORMATION eres el proceso de apertura con sólo SINCRONIZAR el acceso. A ver si agrega | PROCESS_QUERY_INFORMATION si funciona.

  3. 1

    Si sólo quieres P2 a hacer algo cuando P1 sale, no hay otra manera que es probablemente más fácil: han P1 crear una tubería y dejar P2 heredar una manija para que el tubo. En P2, ejecutar una lectura de la tubería. Cuando P2 llamado a la ReadFile devuelve un error de ERROR_BROKEN_PIPE, P1 ha salido.

Dejar respuesta

Please enter your comment!
Please enter your name here