本文介绍了如何在 Windows 中暂停/恢复进程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Unix 中,我们可以暂时挂起进程执行并使用信号 SIGSTOPSIGCONT 恢复它.如何在不编程的情况下暂停 Windows 中的单线程进程?

In Unix we can suspend a process execution temporarily and resume it with signals SIGSTOP and SIGCONT. How can I suspend a single-threaded process in Windows without programming ?

推荐答案

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

You can't do it from the command line, you have to write some code (I assume you're not just looking for an utility otherwise Super User may be a better place to ask). I also assume your application has all the required permissions to do it (examples are without any error checking).

首先获取给定进程的所有线程,然后调用SuspendThread 函数来停止每个线程(并调用ResumeThread 来恢复).它可以工作,但某些应用程序可能会崩溃或挂起,因为线程可能会在任何时候停止并且挂起/恢复的顺序是不可预测的(例如这可能会导致死锁).对于单线程应用程序,这可能不是问题.

First get all the threads of a given process then call the SuspendThread function to stop each one (and ResumeThread to resume). It works but some applications may crash or hung because a thread may be stopped in any point and the order of suspend/resume is unpredictable (for example this may cause a dead lock). For a single threaded application this may not be an issue.

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);
}

请注意,这个函数太天真了,要恢复线程你应该跳过被挂起的线程,因为挂起/恢复顺序很容易导致死锁.对于单线程应用程序,它很繁琐,但很有效.

Please note that this function is even too much naive, to resume threads you should skip threads that was suspended and it's easy to cause a dead-lock because of suspend/resume order. For single threaded applications it's prolix but it works.

从 Windows XP 开始有 NtSuspendProcess 但它未记录.阅读 这篇文章 以获取代码示例(未记录函数的参考:news://comp.os.ms-windows.programmer.win32).

Starting from Windows XP there is the NtSuspendProcess but it's undocumented. Read this post for a code example (reference for undocumented functions: 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 上的备注部分.

This function lets you stop a process (given its Process ID), syntax is very simple: just pass the ID of the process you want to stop et-voila. If you'll make a command line application you'll need to keep its instance running to keep the process suspended (or it'll be terminated). See the Remarks section on MSDN for details.

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

从命令行

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

From Command Line

As I said Windows command line has not any utility to do that but you can invoke a Windows API function from PowerShell. First install Invoke-WindowsApi script then you can write this:

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

当然,如果您经常需要它,您可以为此创建一个别名.

Of course if you need it often you can make an alias for that.

这篇关于如何在 Windows 中暂停/恢复进程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 13:03