2010-12-08 15 views
1

Je ne peux pas sembler utiliser la fonction AssignProcessToJobObject pour affecter le processus en cours à un handle d'objet de travail donné par CreateJobObject. Cela a déjà été demandé à plusieurs reprises sur StackOverflow, mais jusqu'à présent, aucune des solutions (qui se résument habituellement à incorporer un manifeste UAC) ne semble fonctionner pour moi. J'utilise MSVC9 sur Windows 7 pour cela. Voici le code source pour mon exemple d'application et un petit manifeste que je suis l'intégration (qui fixe soi-disant problème - mais pas pour moi):Comment affecter le processus en cours à un nouvel objet de travail?

Mon exemple d'application (main.cpp):

#include <windows.h> 

static void dumpLastError() 
{ 
    LPVOID lpMsgBuf; 
    DWORD dw = GetLastError(); 

    FormatMessage(
     FORMAT_MESSAGE_ALLOCATE_BUFFER | 
     FORMAT_MESSAGE_FROM_SYSTEM, 
     NULL, 
     dw, 
     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
     (LPTSTR) &lpMsgBuf, 
     0, NULL); 
    OutputDebugStringA((LPTSTR)lpMsgBuf); 

    LocalFree(lpMsgBuf); 
} 

int main() 
{ 
    HANDLE job = CreateJobObjectA(NULL, "demo job 123"); 
    if (!job) { 
     OutputDebugStringA("CreateJobObject failed"); 
     dumpLastError(); 
     return 1; 
    } 

    if (!AssignProcessToJobObject(job, GetCurrentProcess())) { 
     OutputDebugStringA("AssignProcessToJobObject failed"); 
     dumpLastError(); 
     return 1; 
    } 

    return 0; 
} 

Le manifeste UAC (main.exe.manifest):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
    <ms_asmv3:trustInfo xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3"> 
     <ms_asmv3:security> 
     <ms_asmv3:requestedPrivileges> 
      <ms_asmv3:requestedExecutionLevel level="requireAdministrator"/> 
     </ms_asmv3:requestedPrivileges> 
     </ms_asmv3:security> 
    </ms_asmv3:trustInfo> 
</assembly> 

Je construis cet exemple en exécutant

cl main.cpp 
mt -manifest main.exe.manifest -outputresource:main.exe;1 

Malheureusement, l'exécution de mon exemple main.exe après ces étapes génère toujours une erreur «Accès refusé» dans la sortie de débogage lors de la tentative de l'appel AssignProcessToJobObject. Est-ce que quelqu'un sait pourquoi c'est?

+0

Utilisez-vous cygwin par hasard? Ou sont vos commandes build/run dans une fenêtre cmd? –

+0

@Ryan Calhoun: Non, je n'utilise pas Cygwin mais j'utilise PyCmd (un simple remplacement de cmd.exe). C'est une question intéressante! Je viens de l'essayer depuis cmd.exe et maintenant ça a l'air de marcher! Impair. –

Répondre

2

J'ai suivi un certain nombre de discussions à un moment concernant les objets de travail et les manifestes de l'UAC. La seule information qui m'a aidé pour le même problème que vous avez était que cette fonctionnalité de sécurité (introduite dans Vista) n'est apparemment pas appliquée lorsqu'elle est exécutée à partir d'un cmd.

Je suppose que vous lancez PyCmd à partir du menu Démarrer. Essayez de le lancer à partir de cmd, et je parie que le problème disparaîtra là aussi.

Ce que je fini par faire (pour exécuter mintty avec Cygwin) était de faire un mintty.bat qui dit

start mintty.exe 

puis un raccourci vers mintty.bat qui avait une propriété définie pour exécuter « minimisais » (J'oublie le libellé exact). Cela permet au shell que je voulais être lancé à partir du menu Démarrer et fonctionne toujours comme s'il avait été lancé à partir de cmd.exe.

En note, j'aimerais que quelqu'un vienne expliquer le problème au niveau de la construction et comment le résoudre.

+0

Je n'ai aucune idée du problème UAC ou pourquoi cmd fait une différence, mais vous pouvez couper le fichier .bat en définissant votre cible de raccourci comme suit: 'C: \ Windows \ system32 \ cmd.exe/c start C : \ cygwin \ bin \ mintty.exe -' – ak2

+0

Merci, j'ai eu un problème avec ce sujet sous Windows 7, votre note m'aide beaucoup. – MRM

4

Je sais que c'est une vieille question, mais j'avais récemment le même problème. Comme suggéré, j'ai utilisé la solution de contournement de la ligne de commande jusqu'à il y a quelques minutes, j'ai trouvé this post.

Depuis que je créais le processus, je viens de suivre les instructions sur l'article en ajoutant CREATE_BREAKAWAY_FROM_JOB aux drapeaux de création de processus:

CreateProcess(szPath, NULL, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi) 

avec

CreateProcess(szPath, NULL, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS | CREATE_BREAKAWAY_FROM_JOB, NULL, NULL, &si, &pi) 

Je l'ai testé et il fonctionne comme prévu, le processus est assigné au travail, pas de manifeste UAC, pas de ligne de commande.

Espérons que cela vous aidera, vous ou toute autre personne ayant ce problème.

+0

+1 Ah, très intéressant! Je connaissais 'CREATE_BREAKAWAY_FROM_JOB', mais je n'ai pas vérifié explicitement si je le définissais dans tous les cas. Merci d'avoir pris le temps de partager cela. :-) –

+0

La documentation pertinente est ici (https://msdn.microsoft.com/en-us/library/windows/desktop/ms681949(v=vs.85).aspx): Si le processus est surveillé par le Program Compatibility Assistant (PCA), il est placé dans un travail de compatibilité. Par conséquent, le processus doit être créé en utilisant CREATE_BREAKAWAY_FROM_JOB avant de pouvoir être placé dans un autre travail. Vous pouvez également incorporer un manifeste d'application qui spécifie un niveau de contrôle de compte d'utilisateur (UAC) dans votre application et PCA n'ajoutera pas le processus au travail de compatibilité. –

+0

C'est tout à fait une trouvaille. Je n'aurais jamais pensé qu'un processus nouvellement créé serait immédiatement ajouté à un travail que je n'ai pas créé moi-même, évidemment en créant CreateProcess. Bon à savoir! – Jinxed