В Unix мы можем временно приостановить выполнение процесса и возобновить его с помощью сигналов SIGSTOP
и SIGCONT
. Как приостановить однопоточный процесс в Windows без программирования?
Как приостановить/возобновить процесс в Windows?
Ответ 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
. Он приостанавливает/возобновляет процесс по его идентификатору.