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
がありますが、それはundocumentedです。コード例については この投稿 をお読みください(文書化されていない関数のリファレンス: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
を使用できます。
この関数を使用すると、プロセスを(プロセスIDを指定して)停止できます。構文は非常に簡単です。et-voilaを停止するプロセスのIDを渡すだけです。コマンドラインアプリケーションを作成する場合は、インスタンスを実行したままにしてプロセスを中断する(または終了する)必要があります。詳細については、MSDNの備考セクションを参照してください。
void suspend(DWORD processId)
{
DebugActiveProcess(processId);
}
前述したように、Windowsコマンドラインにはそれを行うユーティリティはありませんが、PowerShellからWindows API関数を呼び出すことができます。最初に Invoke-WindowsApi スクリプトをインストールしてから、これを記述できます。
Invoke-WindowsApi "kernel32" ([bool]) "DebugActiveProcess" @([int]) @(process_id_here)
もちろん、頻繁に必要な場合は、alias
を作成できます。
外部ツールがなくても、リソースモニターを開き、CPUまたは[概要]タブでプロセスを右クリックしてプロセスの一時停止を選択することで、Windows 7または8でこれを簡単に実行できます。リソースモニターは、タスクマネージャーの[パフォーマンス]タブから起動できます。
SysInternals(procexp.exe)の(非常に古い)プロセスエクスプローラーを使用します。これは、標準のタスクマネージャーの代替/追加であり、そこからプロセスを一時停止できます。
編集:MicrosoftはSysInternalsを購入しました、URL: procExp.exe
それ以外は、プロセスの優先度を低く設定して、他のプロセスの邪魔にならないようにすることができますが、これはプロセスを中断しません。
PsSuspendSysInternals
スイートのコマンドラインユーティリティ。 IDによってプロセスを一時停止/再開します。
さて、Process Explorerには中断オプションがあります。プロセス列でプロセスを右クリックして、中断を選択できます。再開する準備ができたら、右クリックして、再開を選択します。 Process Explorerはここから入手できます。
http://technet.Microsoft.com/en-us/sysinternals/bb896653.aspx
PsSuspend 、 Vadzim で述べたように、pidだけでなく、名前でプロセスを一時停止/再開します。
OneDriveプロセスの単純なトグルスクリプトでPsSuspendと PsList (PsToolsスイートの別のツール)の両方を使用します。より多くの帯域幅が必要な場合は、OneDrive同期を一時停止し、その後、発行してプロセスを再開します同じミニスクリプト:
PsList -d OneDrive|find/i "suspend" && PsSuspend -r OneDrive || PsSuspend OneDrive
PsSuspendSysInternals
スイートのコマンドラインユーティリティ。 IDによってプロセスを一時停止/再開します。
#pragma comment(lib,"ntdll.lib")
EXTERN_C NTSTATUS NTAPI NtSuspendProcess(IN HANDLE ProcessHandle);
void SuspendSelf(){
NtSuspendProcess(GetCurrentProcess());
}
ntdllにはエクスポートされた関数NtSuspendProcessが含まれており、プロセスにハンドルを渡してトリックを実行します。