web-dev-qa-db-fra.com

Comment suspendre/reprendre un processus sous Windows?

Sous Unix, nous pouvons suspendre temporairement l’exécution d’un processus et le reprendre avec les signaux SIGSTOP et SIGCONT. Comment suspendre un processus mono-thread sous Windows sans programmation? 

61
Michael

Vous ne pouvez pas le faire depuis la ligne de commande, vous devez écrire du code (je suppose que vous ne recherchez pas seulement un utilitaire, sinon Super User pourrait être un meilleur endroit pour demander). Je suppose également que votre application dispose de toutes les autorisations requises pour le faire (les exemples se font sans vérification d'erreur).

Façon difficile

Obtenez d’abord tous les threads d’un processus donné, puis appelez la fonction SuspendThread pour les arrêter (et ResumeThread pour les reprendre). Cela fonctionne, mais certaines applications peuvent tomber en panne ou être bloquées car un thread peut être arrêté à tout moment et que l'ordre de suspension/reprise est imprévisible (par exemple, cela peut provoquer un blocage). Pour une application à thread unique, cela peut ne pas être un problème.

void suspend(DWORD processId)
{
    HANDLE hThreadSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);

    THREADENTRY32 threadEntry; 
    threadEntry.dwSize = sizeof(THREADENTRY32);

    Thread32First(hThreadSnapshot, &threadEntry);

    do
    {
        if (threadEntry.th32OwnerProcessID == processId)
        {
            HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE,
                threadEntry.th32ThreadID);

            SuspendThread(hThread);
            CloseHandle(hThread);
        }
    } while (Thread32Next(hThreadSnapshot, &threadEntry));

    CloseHandle(hThreadSnapshot);
}

Veuillez noter que cette fonction est même trop naïve. Pour reprendre les discussions, vous devez ignorer les discussions qui ont été suspendues et il est facile de créer un blocage en raison de l'ordre de suspension/reprise. Pour les applications à un seul thread, c'est prolixe mais cela fonctionne. 

Manière non documentée

À partir de Windows XP, il y a la NtSuspendProcess mais c'est undocumented. Lisez cet article pour un exemple de code (référence pour les fonctions non documentées: news: //comp.os.ms-windows.programmer.win32).

typedef LONG (NTAPI *NtSuspendProcess)(IN HANDLE ProcessHandle);

void suspend(DWORD processId)
{
    HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId));

    NtSuspendProcess pfnNtSuspendProcess = (NtSuspendProcess)GetProcAddress(
        GetModuleHandle("ntdll"), "NtSuspendProcess");

    pfnNtSuspendProcess(processHandle);
    CloseHandle(processHandle);
}

"Debugger" Way

Pour suspendre un programme, c'est ce que fait habituellement un débogueur. Pour ce faire, vous pouvez utiliser la fonction DebugActiveProcess . Il va suspendre l'exécution du processus (avec tous les threads tous ensemble). Pour reprendre, vous pouvez utiliser DebugActiveProcessStop.

Cette fonction vous permet d'arrêter un processus (en fonction de son ID de processus). La syntaxe est très simple: il vous suffit de passer l'ID du processus que vous souhaitez arrêter et-voila. Si vous créez une application en ligne de commande, vous devrez maintenir son instance en cours d'exécution pour que le processus soit suspendu (sinon, elle sera terminée). Consultez la section Remarks sur MSDN pour plus de détails.

void suspend(DWORD processId)
{
    DebugActiveProcess(processId);
}

À partir de la ligne de commande

Comme je l'ai dit, la ligne de commande Windows n'a aucun utilitaire pour le faire, mais vous pouvez appeler une fonction API Windows à partir de PowerShell. Commencez par installer Invoke-WindowsApi script, puis écrivez ceci:

Invoke-WindowsApi "kernel32" ([bool]) "DebugActiveProcess" @([int]) @(process_id_here)

Bien sûr, si vous en avez souvent besoin, vous pouvez en créer une alias.

86
Adriano Repetti

Ceci est possible sans outil externe sous Windows 7 ou 8, en ouvrant le moniteur de ressources et dans l'onglet CPU ou Aperçu en cliquant avec le bouton droit de la souris sur le processus et en sélectionnant Suspend Process . commencé à partir de l'onglet Performances du gestionnaire de tâches.

79
Sigroad

J'utilise (un très ancien) processus Explorer de SysInternals (procexp.exe). C'est un remplacement/ajout au gestionnaire de tâches standard, vous pouvez suspendre un processus à partir de là.

Edit: Microsoft a acheté via SysInternals, url: procExp.exe

En dehors de cela, vous pouvez définir la priorité du processus sur faible afin qu'elle ne gêne pas d'autres processus, mais cela ne suspend pas le processus.

39
Zordey

PsSuspend Utilitaire de ligne de commande de la suite SysInternals. Il suspend/reprend un processus par son identifiant. 

18
AlexeyDaryin

Eh bien, Process Explorer a une option de suspension. Vous pouvez cliquer avec le bouton droit sur un processus dans la colonne Processus et sélectionner Suspendre. Une fois que vous êtes prêt à le reprendre, cliquez avec le bouton droit de la souris et sélectionnez CV. Process Explorer peut être obtenu ici:

http://technet.Microsoft.com/en-us/sysinternals/bb896653.aspx

13
shivesh suman

PsSuspend , comme mentionné par Vadzim , même suspend/reprend un processus par son nom, pas seulement par pid.

J'utilise à la fois PsSuspend et PsList (un autre outil de la suite PsTools) dans un script de basculement simple pour le processus OneDrive: si j'ai besoin de plus de bande passante, je suspends la synchronisation OneDrive, puis je reprends le processus en relançant le même mini script:

PsList -d OneDrive|find/i "suspend" && PsSuspend -r OneDrive || PsSuspend OneDrive

PsSuspend utilitaire de ligne de commande de SysInternals suite. Il suspend/reprend un processus par son identifiant.

2
Stijn Bousard
#pragma comment(lib,"ntdll.lib")
EXTERN_C NTSTATUS NTAPI NtSuspendProcess(IN HANDLE ProcessHandle);

void SuspendSelf(){
    NtSuspendProcess(GetCurrentProcess());
}

ntdll contient la fonction exportée NtSuspendProcess, transmettez le handle à un processus pour qu'il fasse l'affaire.

0
coltonon