[解決済み] 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);
}
スレッドを再開するには、中断されたスレッドをスキップする必要があり、サスペンド/レジュームの順序のためにデッドロックを引き起こすことが容易であることに注意してください。シングルスレッド・アプリケーションでは、冗長ですが動作します。
文書化されていない方法
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
.
この関数は、プロセス ID を指定してプロセスを停止させることができます。構文は非常に簡単で、停止させたいプロセスの ID を渡すだけで完了です。コマンドラインアプリケーションを作成する場合、プロセスを停止させるためにそのインスタンスを実行し続ける必要があります(さもなければ終了されます)。そのためには 備考 のセクションを参照してください。
void suspend(DWORD processId)
{
DebugActiveProcess(processId);
}
コマンドラインから
Windowsのコマンドラインにはそのためのユーティリティがないと言いましたが、PowerShellからWindowsのAPI関数を呼び出すことは可能です。まず、以下のファイルをインストールします。 インヴォークウィンドウズアピ スクリプトをインストールしてから、次のように記述します。
Invoke-WindowsApi "kernel32" ([bool]) "DebugActiveProcess" @([int]) @(process_id_here)
もちろん、頻繁に必要な場合は
alias
を作ることができます。
関連
-
[解決済み】Macでポート3000をロックしているプロセスを検索(およびkill)する
-
PID 4の "Unable to open process "によってポート80が使用されています。
-
[解決済み] Windowsにpipをインストールするにはどうしたらいいですか?
-
[解決済み] プロセスとスレッドの違いは何ですか?
-
[解決済み] 何が私のプロセスを殺したのか、なぜなのか?
-
[解決済み] C#のWindowsコンソールアプリで現在行を更新するにはどうしたらいいですか?
-
[解決済み] Windowsでプロセスを強制終了させる
-
[解決済み】WindowsでTCPまたはUDPポートをリッスンしているプロセスを見つけるにはどうすればよいですか?
-
[解決済み】PowerShellスクリプトを実行する方法
-
[解決済み] RS232シリアルポートのフェイク
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Windowsで動作するEmacsの.emacsファイルはどこにあるのですか?
-
[解決済み] VIM Ctrl-VとWindows Pasteの競合
-
[解決済み] バッチファイルのアットマーク(@)とは何ですか、そして何をするのですか?
-
[解決済み] プログラムファイルx86の環境変数を取得するには?
-
[解決済み] git - サーバーのホストキーがキャッシュされない
-
[解決済み] Sublimeをデフォルトエディタに
-
[解決済み] ホスト外(同一ネットワーク)からDockerコンテナに接続する方法 [Windows]
-
[解決済み] Windowsバッチスクリプトによるプログラムの起動とコンソールの終了
-
[解決済み] RS232シリアルポートのフェイク
-
[解決済み] Windowsで特定のファイルが開かれているかどうかを確認するにはどうすればよいですか?[クローズド]