Подтвердить что ты не робот

Как приостановить/возобновить процесс в Windows?

В Unix мы можем временно приостановить выполнение процесса и возобновить его с помощью сигналов SIGSTOP и SIGCONT. Как приостановить однопоточный процесс в Windows без программирования?

4b9b3361

Ответ 1

Вы не можете сделать это из командной строки, вам нужно написать какой-то код (я полагаю, вы не просто ищете утилиту, иначе Super User может быть лучше спросить). Я также предполагаю, что ваше приложение имеет все необходимые разрешения для этого (примеры без проверки ошибок).

Жесткий путь

Сначала получите все потоки заданного процесса, затем вызовите функцию SuspendThread, чтобы остановить их (и ResumeThread для возобновления). Он работает, но некоторые приложения могут сбой или зависание, потому что поток может быть остановлен в любой точке, а порядок приостановки/возобновления непредсказуем (например, это может привести к блокировке блокировки). Для однопоточного приложения это может не быть проблемой.

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

Обратите внимание, что эта функция даже слишком наивна, чтобы возобновить потоки, вы должны пропустить потоки, которые были приостановлены, и легко вызвать блокировку блокировки из-за приостановки/возобновления заказа. Для однопоточных приложений он работает, но он работает.

Недокументированный способ

Начиная с Windows XP существует NtSuspendProcess, но он недокументирован. Прочитайте этот пост для примера кода (ссылка для недокументированных функций: 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);
}

Путь отладчика

Чтобы приостановить выполнение программы, что обычно делает отладчик, для этого вы можете использовать функцию DebugActiveProcess. Он приостановит выполнение процесса (со всеми потоками все вместе). Чтобы возобновить работу, вы можете использовать DebugActiveProcessStop.

Эта функция позволяет остановить процесс (учитывая его идентификатор процесса), синтаксис очень прост: просто передайте идентификатор процесса, который вы хотите остановить et-voila. Если вы сделаете приложение с командной строкой, вам нужно будет продолжать использовать его экземпляр, чтобы приостановить процесс (или он будет завершен). Подробнее см. В разделе "Примечания" в MSDN.

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

Из командной строки

Как я уже сказал, в командной строке Windows нет никакой утилиты, но вы можете вызвать функцию Windows API из PowerShell. Сначала установите Invoke-WindowsApi script, тогда вы можете написать это:

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

Конечно, если вам это нужно, вы можете сделать alias для этого.

Ответ 2

Без какого-либо внешнего инструмента вы можете просто выполнить это в Windows 7 или 8, открыв монитор ресурсов и вкладку CPU или Overview, щелкнув правой кнопкой мыши процесс и выбрав Suspend Process. Монитор ресурсов можно запустить со вкладки "Производительность" диспетчера задач.

Ответ 3

Я использую (очень старый) проводник процессов из SysInternals (procexp.exe). Это замена/добавление стандартного диспетчера задач, вы можете приостановить процесс оттуда.

Изменить: Microsoft купила через SysInternals, url: procExp.exe

Кроме этого вы можете установить приоритет процесса на низкий, чтобы он не мешал другим процессам, но это не приостанавливает процесс.

Ответ 4

Утилита командной строки PsSuspend из пакета SysInternals. Он приостанавливает/возобновляет процесс по его идентификатору.

Ответ 5

Хорошо, у Process Explorer есть опция suspend. Вы можете щелкнуть правой кнопкой мыши процесс в столбце процесса и выбрать приостановить. Когда вы будете готовы возобновить его снова, щелкните правой кнопкой мыши и на этот раз выберите резюме. Проводник процесса можно получить здесь:

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

Ответ 6

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

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

ntdll содержит экспортированную функцию NtSuspendProcess, передающую дескриптор процессу для выполнения задачи.

Ответ 7

PsSuspend, как упомянул Вадим, даже приостанавливает/возобновляет процесс по имени.

Я использую переключатель для процесса OneDrive: если мне нужна большая пропускная способность, я приостанавливаю синхронизацию OneDrive, после чего возобновляю процесс, выпуская тот же мини-скрипт:

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

Утилита командной строки PsSuspend из пакета SysInternals. Он приостанавливает/возобновляет процесс по его идентификатору.