Pourquoi AssignProcessToJobObject échoue-t-il sur XP avec l’erreur Access Denied?

J’ai le code suivant:

#include  #include  #include  #pragma comment ( lib, "shlwapi.lib" ) int __cdecl wmain( int argc, PWSTR argv[] ) { HANDLE Job( CreateJobObject( NULL, NULL ) ); if( !Job ) { wprintf( L"Could not create job object, error %d\n", GetLastError() ); return 0; } HANDLE IOPort( CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 0, 1 ) ); if( !IOPort ) { wprintf( L"Could not create IO completion port, error %d\n", GetLastError() ); return 0; } JOBOBJECT_ASSOCIATE_COMPLETION_PORT Port; Port.CompletionKey = Job; Port.CompletionPort = IOPort; if( !SetInformationJobObject( Job, JobObjectAssociateCompletionPortInformation, &Port, sizeof( Port ) ) ) { wprintf( L"Could not associate job with IO completion port, error %d\n", GetLastError() ); return 0; } PROCESS_INFORMATION ProcessInformation; STARTUPINFO StartupInfo = { sizeof(StartupInfo) }; PWSTR CommandLine = PathGetArgs(GetCommandLine()); if( !CreateProcess( NULL, CommandLine, NULL, NULL, FALSE, CREATE_NEW_CONSOLE | CREATE_SUSPENDED, NULL, NULL, &StartupInfo, &ProcessInformation ) ) { wprintf( L"Could not run process, error %d\n", GetLastError() ); return 0; } if( !AssignProcessToJobObject( Job, ProcessInformation.hProcess ) ) { wprintf( L"Could not assign process to job, error %d\n", GetLastError() ); return 0; } ResumeThread( ProcessInformation.hThread ); CloseHandle( ProcessInformation.hThread ); CloseHandle( ProcessInformation.hProcess ); DWORD CompletionCode; ULONG_PTR CompletionKey; LPOVERLAPPED Overlapped; int ProcessCount = 0; while ( GetQueuedCompletionStatus( IOPort, &CompletionCode, &CompletionKey, &Overlapped, INFINITE ) && CompletionCode != JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO ) { if ( CompletionCode == JOB_OBJECT_MSG_NEW_PROCESS ) ProcessCount++; if ( ( CompletionCode == JOB_OBJECT_MSG_EXIT_PROCESS ) || ( CompletionCode == JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS) ) ProcessCount--; wprintf( L"Waiting for %d processes to finish...\n", ProcessCount ); } wprintf( L"All done\n" ); return 0; } 

Ce code fonctionne correctement sous Windows 7, mais AssignProcessToJobObject échoue avec le code d’erreur 5 (Accès refusé) sous Windows XP. Selon MSDN: Windows 7, Windows Server 2008 R2, Windows XP avec SP3, Windows Server 2008, Windows Vista et Windows Server 2003: le processus ne doit pas déjà être affecté à un travail; Si c’est le cas, la fonction échoue avec ERROR_ACCESS_DENIED. Ce comportement a changé à partir de Windows 8 et Windows Server 2012.

Est-ce que quelqu’un pourrait m’aider à corriger ce code?

Merci!

Mise à jour: j’ai pu trouver le problème, mais je ne sais toujours pas comment le résoudre 🙁 Le problème, c’est que je me connecte à une machine XP, avec un utilisateur standard (sans droits d’administrateur), et ouvre un cmd. Avec les runas (avec un utilisateur disposant des droits d’administrateur), cette cmd sera créée en tant qu’ajobobject. Dans l’explorateur de processus, vous pouvez voir ceci. Si je veux démarrer mon application à partir de cette cmd, AssignProcessToJobObject échouera avec erro Access denies, car thios cmd est déjà affecté à un travail.

Y a-t-il un moyen de résoudre mon problème?

Il se peut que l’environnement dans lequel le code est exécuté ait déjà créé un travail dans lequel le processus parent est inclus. Vous pouvez essayer d’append CREATE_BREAKAWAY_FROM_JOB aux indicateurs de création de processus, ce qui peut permettre au nouveau processus de rompre avec le travail qu’il est actuellement. dans.

Je ne me souviens pas si Visual Studio exécute des tâches dans un travail lorsqu’il exécute des tâches sous le débogueur.

Vous pouvez également essayer d’interroger le statut du travail en cours pour les processus en cours, car cela montrera s’il fait déjà partie d’un travail.