2

我的理解是,当您在 Windows XP 中通过任务管理器终止 C++ 应用程序时,该应用程序仍然“干净”地被破坏 - 即调用堆栈将展开并且所有相关的对象析构函数都将被调用。不确定我的理解是否有误。

是否可以在不展开堆栈的情况下立即终止这样的应用程序?

例如,应用程序可以使用 RAII 模式,当对象被破坏时,这些模式将破坏或释放资源。如果通过任务管理器的传统“终止进程”是正常的,那么提供一种立即终止应用程序的方法将允许我测试不正常的关机(例如断电)。

编辑:

澄清一下,我正在寻找一个允许我这样做的现有实用程序或程序。我应该能够在我没有源代码的程序上使用该解决方案,这意味着编程解决方案实际上是不可接受的。

编辑:

只是为了提供更多上下文,有时我必须使用非常侵入性的第 3 方服务(例如,每隔一小时就唠叨我重新启动)。因为我知道我不需要重新启动,所以我想终止进程/服务,这样它就不会再唠叨我了。不幸的是,一些第 3 方开发人员“聪明”到足以阻止我这样做,当我通过任务管理器终止进程时,系统将立即重新启动(我猜是使用 RAII 来实现这一点)。

4

9 回答 9

8

我相信任务管理器通过发送 WM_CLOSE 消息尝试“很好”关闭,然后如果应用程序没有响应,它就会被杀死。

此调用应立即终止进程而不会发出警告:

终止进程

例如:

TerminateProcess(GetCurrentProcess(), 1);

更新:

你可能会觉得这篇文章很有趣:

退出时间:退出 C++ 程序

更新 2:

我应该能够在我没有源代码的程序上使用该解决方案

嗯,这在 99.9% 的情况下都是不受欢迎的行为。

SysInternals 有一个名为pskill

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

但我不确定它有多“好”。

你可能需要自己动手,但这应该很容易:

DWORD pid = <get pid from command line>;

TerminateProcess(OpenProcess(PROCESS_TERMINATE, FALSE, pid));
于 2009-08-26T01:52:18.743 回答
2

不依赖 3rd-party 工具的标准 Windows 方法是使用taskkill /f

taskkill /f <process-id>
taskkill /f /im <process-executable-name> 

/f在这里表示“强制”,并确保进程无条件立即终止,没有查询或警告。

于 2009-08-26T02:37:17.593 回答
2

除非我大错特错(我只是做了一些测试来确认),否则任务管理器会根据您使用的选项卡尝试以不同的方式关闭程序。如果通过 Applications 选项卡并按下 End Task,它将尝试通过首先发送 WM_CLOSE 干净地关闭程序。但是,如果通过 Processes 选项卡并按下 End Process,它似乎使用了 TerminateProcess 类似的东西,这意味着没有堆栈展开等。

因此,首先,如果您没有在“进程”选项卡上使用“结束进程”,请尝试一下。

如果这是您已经尝试过的,并且他们的软件仍然设法以某种方式重新启动系统,那么事情就会变得更加复杂。其他人可能在关于存在额外流程的正确轨道上。

于 2009-08-26T03:52:21.917 回答
0

我相信 C 标准库方法exit(0); 将这样做,中止程序而不调用任何析构函数、释放器等。

试试看,让我知道它是否满足您的需求?

于 2009-08-26T01:53:02.580 回答
0

看起来 abort() 会给你一个异常退出。

ANSI 4.10.4.1 abort 函数对打开和临时文件的行为 abort 函数不会关闭打开或临时文件。它不会刷新流缓冲区 [来源]

Abort current process 中止程序异常终止的进程。该函数生成 SIGABRT 信号,默认情况下会导致程序终止 > 将不成功的终止错误代码返回给主机环境。该程序在不为自动或静态存储持续时间的对象执行析构函数的情况下终止,并且不调用任何 atexit 函数。该函数永远不会返回给它的调用者。 [来源]

于 2009-08-26T01:58:04.400 回答
0

我会按照上面 Tim的建议尝试PSKill。我猜这也会失败。如果 3rd 方服务真的很想避免死亡,那么服务定义可能会设置为“rebo​​ot on crash”。另一种常见的方法是使用另一个服务来监视主要服务。主要服务通常设置一个全局事件或使用看门狗服务监视的其他通知机制。如果主服务没有通知看门狗,那么看门狗会重新启动计算机。

于 2009-08-26T02:16:34.927 回答
0

恰当命名的Kill Tool,可从 Microsoft 下载获得。也是 Windbg 套件的一部分。

Kill 工具 kill.exe 终止一个或多个进程及其所有线程。此工具仅适用于本地计算机上运行的进程。

kill /f <process>

例如,kill /f lsass(开个玩笑,不要杀死LSA!)。如果您想自己动手,TerminateProcess 是您的最佳选择。

于 2009-08-26T02:17:25.707 回答
0

标准库中的 C 函数 abort() 将立即终止您的应用程序而无需清理。

C++ 定义了一个标准的全局函数 terminate()。调用它也会立即退出您的应用程序。

从技术上讲,terminate() 的行为可以被 set_terminate 函数覆盖。它默认调用 abort。

于 2009-08-26T02:27:53.817 回答
0

周围有一些实用程序可以禁止重新启动。

例如, HideToolz就是这样做的——在某处埋有一个复选框,它会在某事启动重启时询问您。它被许多防病毒软件检测为 rootkit(确实如此,但这个被认为是驯服的),因此在您无法完全控制的系统上运行可能是探测性的(当域策略要求防病毒软件等时)

于 2009-08-26T02:53:06.037 回答