У Unix ми можемо тимчасово призупинити виконання процесу та відновити його за допомогою сигналів SIGSTOP
і SIGCONT
. Як я можу призупинити однопотоковий процес у Windows без програмування?
У Unix ми можемо тимчасово призупинити виконання процесу та відновити його за допомогою сигналів SIGSTOP
і SIGCONT
. Як я можу призупинити однопотоковий процес у Windows без програмування?
Відповіді:
Ви не можете зробити це з командного рядка, вам потрібно написати якийсь код (я припускаю, що ви не просто шукаєте утиліту, інакше Супер користувач може бути кращим місцем для запитання). Я також припускаю, що ваша програма має всі необхідні дозволи для цього (приклади без перевірки помилок).
Спочатку отримайте всі потоки даного процесу, потім викличте 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);
}
Зверніть увагу, що ця функція навіть занадто наївна, для відновлення потоків слід пропускати потоки, які були призупинені, і це може спричинити блокування через замовлення призупинення / відновлення. Для однопотокових додатків це prolix, але він працює.
Починаючи з 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, тоді ви можете написати це:
Invoke-WindowsApi "kernel32" ([bool]) "DebugActiveProcess" @([int]) @(process_id_here)
Звичайно, якщо вам це потрібно часто, ви можете зробити alias
для цього.
Invoke-WindowsApi
) , що дозволить вам Invoke в Windows API , (PASCAL
угода про виклики, звичайно WINAPI
) функцію C. Він не є частиною PowerShell, тоді його потрібно завантажити та встановити окремо .
Без будь-якого зовнішнього інструменту ви можете просто досягти цього в Windows 7 або 8, відкривши монітор ресурсів і на вкладці ЦП або Огляд правою кнопкою миші на процесі та вибравши Призупинити процес . Монітор ресурсів можна запустити з вкладки "Ефективність" диспетчера завдань.
procexp.exe
!
Я використовую (дуже старий) провідник процесів від SysInternals (procexp.exe). Це заміна / доповнення до стандартного диспетчера завдань, звідти ви можете призупинити процес.
Редагувати: Microsoft придбала SysInternals, url: procExp.exe
Крім цього, ви можете встановити пріоритет процесу на низький, щоб він не заважав іншим процесам, але це не призупинить процес.
Ну, у Process Explorer є опція призупинення. Ви можете клацнути правою кнопкою миші процес у стовпці процесу та вибрати призупинити. Як тільки ви будете готові відновити його знову, клацніть правою кнопкою миші, і цього разу виберіть відновити. Провідник процесів можна отримати тут:
http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx
PsSuspend , як згадував Вадзім , навіть призупиняє / відновлює процес за назвою, а не лише за допомогою pid.
Я використовую і PsSuspend, і PsList (інший інструмент із набору PsTools) у простому сценарії перемикання для процесу OneDrive: якщо мені потрібна більша пропускна здатність, я призупиняю синхронізацію OneDrive, після чого відновлюю процес, видаючи той самий міні-сценарій:
PsList -d onedrive|find/i "suspend" && PsSuspend -r onedrive || PsSuspend onedrive
Утиліта командного рядка PsSuspend із SysInternals
набору. Він призупиняє / відновлює процес за своїм ідентифікатором.