Ответ 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
для этого.