进程终止时释放资源

发布于 2024-07-13 05:21:53 字数 49 浏览 9 评论 0原文

当进程被任务管理器等进程终止时,如何释放资源? 有没有办法在进程关闭之前调用函数?

How I can deallocate resources when the process gets killed by, for example, the Task Manager? Is there a way to call a function before the process gets closed?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

爱已欠费 2024-07-20 05:21:54

您可以尝试将整个过程包装在 try/finally 语句中(将释放内容放在 finally 子句中),但在某些情况下,即使这样也是不够的。

实际上,我认为您可以从进程中启动一个后台线程来执行所有操作,并使用主线程执行 Thread.Join() 操作,这样如果子线程中出现问题,主线程仍然能够解决问题。 当然,如果整个过程由于某种原因终止,这将不起作用。

您还可以启动一个子进程并调用 Process.WaitForExit() 但我不确定您的 shell 相关的东西是否可以使用多进程方法。

You could try wrapping your whole process in a try/finally statement (you put the deallocation stuff in the finally clause), but in some cases even that will not be enough.

Actually, I think you could launch a background thread from your process to do all the stuff and Thread.Join() with your main thread so that if something goes wrong in the child thread, the main thread will be still able to get things right. Of course, this will not work if the whole process gets terminated for some reason.

You could also launch a child process and call Process.WaitForExit() but I'm not sure if your shell-related thing could work with a multi-process approach.

无人问我粥可暖 2024-07-20 05:21:53

如果您的进程被终止,您实际上无能为力。 根据定义,杀死一个进程就是杀死它。 该进程没有机会运行任何代码。 这很大程度上是“设计使然”。

想象一下,您可以注册一个例程,当您的进程被用户(或另一个进程)终止时调用该例程。 它会做什么? 进程中的所有其他线程都将处于不确定状态,您将如何与它们同步? 请记住,这个想法是需要终止该进程。

另一种情况甚至更困难:您的代码是良性的,并试图做正确的事情 - 例如清理并成为一个好的系统公民。 有些代码不是。 想象一下,如果操作系统允许为正在被杀死的进程运行代码,这对恶意软件作者来说将是多么大的好处。 对于以标准用户权限运行的恶意进程来说,这已经足够糟糕了,对于任何以管理权限运行的恶意进程来说,这都非常糟糕。

关键终结和结构化异常处理不会解决这个根本问题。

从好的方面来说,当进程被终止时,操作系统将释放它所知道的所有资源,即内存和内核对象。 那些不会泄漏。 但资源管理器不知道您的进程,因此无法对其进行清理。

解决这个问题的一种方法是建立一个监视进程来跟踪其他进程的状态并对其进行清理。 您可以通过简单的流程或服务来完成此操作。 您还可以考虑某种 shell 扩展,它有自己的线程来执行相同的操作。

There really is nothing you can do if your process is killed. By definition, killing a process is just that - killing it. The process does not get an opportunity to run any code. This is very much "by design".

Imagine that you could register a routine that was called when your process was killed by the user (or by another process). What would it do? All the other threads in your process would be in an indeterminate state, How would you synchronize with them? Remember, the idea is that the process needs to be killed.

The other scenario is even tougher: your code is benign and trying to do the right thing - e.g. clean up and be a good system citizen. Some code isn't. Imagine what a boon to a malware author it would be if the OS allowed code to be run for a process that was being killed. It would be bad enough for malicious processes that were running with standard user privileges, and completely awful for any running with administrative privileges.

Critical finalizes and structured exception handling will not solve this fundamental issue.

ON the upside, the OS will free all the resources it knows about when your process is killed, namely memory and kernel objects. Those will not leak. But explorer doesn't know about your process so it cannot clean up for it.

One way to solve this would be to have a monitoring process that keeps track of your other processes state and cleans up for it. You could do this with a simple process, or with a service. You might also consider some kind of shell extension that had its own thread that did the same thing.

堇年纸鸢 2024-07-20 05:21:53

无法在即将通过调用 TerminateProcess(例如任务管理器或其他进程实用程序(例如 TSKILL 或 TASKKILL))终止的进程中执行任意代码。

无论是关键终结器、普通终结器还是 try/finally 块,当然不仅仅是实现 IDisposable 的对象都不能导致代码在这种情况下执行。 即使 DLL 分离事件也不会通过 TerminateProcess 从进程终止中调用。

您能做的最好的事情就是使用一个看门狗进程来监视您的原始进程并在原始进程终止时执行相关代码。

There is no way to execute arbitrary code upon termination within a process which is about to be killed by a call to TerminateProcess, such as by Task Manager, or another process utility such as TSKILL or TASKKILL.

Neither critical finalizers, nor ordinary finalizers, nor try/finally blocks, and certainly not mere objects which implement IDisposable can cause code to be executed in this scenario. Even DLL detach events will not be invoked from a process termination via TerminateProcess.

The best you can do is to use a watchdog process which monitors your original process and executes relevant code when the original process is terminated.

情深已缘浅 2024-07-20 05:21:53

理论上,操作系统应该在进程被终止后释放资源。 您特别想到什么样的资源?


编辑:

好吧,解释起来有点棘手。 我正在使用一个包装一些操作系统函数来管理一些 Shell 扩展的库。 当应用程序关闭而没有显式调用适当的方法时,所有资源管理器都会冻结,我需要重新启动它。

任何非托管 DLL(根据文档)都应该通过 DLL_PROCESS_DETACH 事件调用; 但是,当通过 TerminateProcess API 终止进程时,不会调用此 DLL_PROCESS_DETACH 事件。

在 Google 上搜索这些条款,结果出现旧的新事物:为什么不能捕获 TerminateProcess?
它表示,“一旦使用 TerminateProcess 终止,该进程中将不再运行用户模式代码。它消失了。

因为您尝试使用的所有内容(即 .NET、Explorer、Shell) ,COM)发生在用户模式下,我认为答案是没有办法做你想做的事。

相反,也许还有另一种方法:例如,通过向 Shell 扩展添加代码,以便它们意识到您的进程是否异常终止。

Theoretically the O/S should deallocate resources after the process is killed. What kind of resource are you thinking of in particular?


Edit:

Ok, it's kinda tricky to explain. I'm using a library that is wrapping some OS functions to manage some Shell Extensions. When the application closes without calling explicitly the appropriate methods, all explorer freezes and I need to restart it.

Any unmanaged DLL is (according to the documentation) supposed to be invoked with a DLL_PROCESS_DETACH event; however, this DLL_PROCESS_DETACH event isn't called when the process is terminated via the TerminateProcess API.

Googling for these terms turned up The Old New Thing : Why can't you trap TerminateProcess?
which says, "Once you kill with TerminateProcess, no more user-mode code will run in that process. It's gone."

Because everything you're trying to work with (i.e. .NET, Explorer, Shell, COM) is happening in user-mode, I think the answer is that there's no way to do what you want.

Instead, perhaps there's another way: for example, by adding code to your Shell extensions so that they realize if your process is abended.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文