如何在Windows中暂停/恢复进程?

时间:2012-06-13 07:35:08

标签: windows process signals

在Unix中,我们可以暂时暂停流程执行,并使用信号SIGSTOPSIGCONT恢复流程执行。如何在没有编程的情况下暂停Windows中的单线程进程?

7 个答案:

答案 0 :(得分:89)

您不能从命令行执行此操作,您必须编写一些代码(我假设您不只是在寻找实用程序,否则超级用户可能是更好的地方)。我还假设您的应用程序具有执行此操作所需的所有权限(示例没有任何错误检查)。

艰难的方式

首先获取给定进程的所有线程,然后调用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,但未记录。阅读this post以获取代码示例(未记录函数的参考: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 et-voila。如果您要创建命令行应用程序,则需要保持其实例运行以保持进程暂停(或者它将被终止)。有关详细信息,请参阅MSDN上的备注部分。

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

从命令行

正如我所说,Windows命令行没有任何实用程序可以执行此操作,但您可以从PowerShell调用Windows API函数。首先安装Invoke-WindowsApi脚本然后你可以这样写:

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

当然,如果您经常需要它,您可以为此alias

答案 1 :(得分:79)

如果没有任何外部工具,您只需在Windows 7或8上完成此操作,方法是打开资源监视器,在CPU或“概述”选项卡上右键单击该过程并选择暂停过程。 可以从任务管理器的“性能”选项卡启动资源监视器。

答案 2 :(得分:40)

我使用来自SysInternals(procexp.exe)的(一个非常古老的)进程资源管理器。它是标准任务管理器的替代/补充,您可以从那里暂停进程。

编辑:微软收购了SysInternals,网址为:procExp.exe

除此之外,您可以将进程优先级设置为低,以免它妨碍其他进程,但这不会暂停进程。

答案 3 :(得分:18)

来自SysInternals套件的

PsSuspend命令行实用程序。它通过其id暂停/恢复进程。

答案 4 :(得分:14)

好吧,Process Explorer有一个暂停选项。您可以右键单击流程列中的流程,然后选择挂起。一旦准备好再次恢复它,请右键单击,这次选择简历。 Process Explorer可以从这里获得:

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

答案 5 :(得分:1)

PsSuspend所述,

Vadzim甚至通过其名称(不仅是pid)暂停/恢复进程。

我在一个简单的切换脚本中将PsSuspend和PsList(PsTools套件中的另一个工具)用于OneDrive进程:如果我需要更多带宽,则暂停OneDrive同步,然后通过发出来恢复进程相同的迷你脚本:

PsList -d onedrive|find/i "suspend" && PsSuspend -r onedrive || PsSuspend onedrive
SysInternals套件中的

PsSuspend命令行实用程序。它通过其ID挂起/恢复进程。

答案 6 :(得分:0)

#pragma comment(lib,"ntdll.lib")
EXTERN_C NTSTATUS NTAPI NtSuspendProcess(IN HANDLE ProcessHandle);

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

ntdll包含导出的函数NtSuspendProcess,将句柄传递给进程即可完成操作。