86

Unixでは、プロセスの実行を一時的に中断し、シグナルSIGSTOPとで再開できSIGCONTます。プログラミングせずにWindowsでシングルスレッドプロセスを一時停止するにはどうすればよいですか?

4

7 に答える 7

107

コマンドラインからそれを行うことはできません。コードを作成する必要があります(ユーティリティを探しているだけではないと思います。そうでない場合は、スーパーユーザーの方が適している可能性があります)。また、アプリケーションにはそれを実行するために必要なすべての権限があると想定しています(例にはエラーチェックがありません)。

ハードウェイ

最初に特定のプロセスのすべてのスレッドを取得してから、関数を呼び出して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

この関数を使用すると、プロセスを停止できます(プロセスIDが指定されている場合)。構文は非常に単純です。停止するプロセスのIDを渡すだけです。コマンドラインアプリケーションを作成する場合は、プロセスを一時停止したままにする(または終了する)ために、インスタンスを実行し続ける必要があります。詳細については、MSDNの「備考」セクションを参照してください。

void suspend(DWORD processId)
{
    DebugActiveProcess(processId);
}

コマンドラインから

私が言ったように、Windowsコマンドラインにはそれを行うためのユーティリティはありませんが、PowerShellからWindowsAPI関数を呼び出すことができます。最初にInvoke-WindowsApiスクリプトをインストールしてから、次のように記述できます。

Invoke-WindowsApi "kernel32" ([bool]) "DebugActiveProcess" @([int]) @(process_id_here)

もちろん、あなたがそれを頻繁に必要とするならば、あなたはそれのaliasために作ることができます。

于 2012-06-13T07:59:04.200 に答える
90

外部ツールがなくても、Windows 7、8、または10でこれを実行するには、リソースモニターを開き、[CPU]または[概要]タブでプロセスを右クリックし、[プロセスの一時停止]を選択します。リソースモニターは、タスクマネージャーの[パフォーマンス]タブから開始できます。

于 2014-02-08T17:46:46.697 に答える
41

私はSysInternals(procexp.exe)の(非常に古い)ProcessExplorerを使用しています。これは、標準のタスクマネージャーの置き換え/追加であり、そこからプロセスを一時停止できます。

編集:MicrosoftはSysInternalsを買収しました。URL:procExp.exe

それ以外の場合は、プロセスの優先度を低く設定して、他のプロセスの邪魔にならないようにすることができますが、これによってプロセスが中断されることはありません。

于 2012-06-13T07:59:43.270 に答える
23

スイートのPsSuspendコマンドラインユーティリティSysInternals。IDによってプロセスを一時停止/再開します。

于 2013-11-21T06:20:00.673 に答える
14

そうですね、ProcessExplorerには一時停止オプションがあります。プロセス列でプロセスを右クリックし、[一時停止]を選択できます。再開する準備ができたら、右クリックして、今度は再開を選択します。Process Explorerは、次の場所から入手できます。

http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx

于 2013-04-12T11:11:17.713 に答える
6

Vadzimが述べているように、PsSuspendは、pidだけでなく、その名前でプロセスを一時停止/再開します。

OneDriveプロセスの単純なトグルスクリプトでPsSuspendとPsList(PsToolsスイートの別のツール)の両方を使用します。より多くの帯域幅が必要な場合は、OneDrive同期を一時停止し、その後、同じミニスクリプトを発行してプロセスを再開します。

PsList -d onedrive|find/i "suspend" && PsSuspend -r onedrive || PsSuspend onedrive

スイートのPsSuspendコマンドラインユーティリティSysInternals。IDによってプロセスを一時停止/再開します。

于 2019-06-21T13:56:28.797 に答える
0
#pragma comment(lib,"ntdll.lib")
EXTERN_C NTSTATUS NTAPI NtSuspendProcess(IN HANDLE ProcessHandle);

void SuspendSelf(){
    NtSuspendProcess(GetCurrentProcess());
}

ntdllには、エクスポートされた関数NtSuspendProcessが含まれており、トリックを実行するためにハンドルをプロセスに渡します。

于 2019-02-11T03:41:58.870 に答える