python :3.4
操作系统:win7/win10
我想用 python 终止正在运行的进程并关闭它打开的所有文件:
for proc in psutil.process_iter():
if proc.name() == 'myprocess.exe':
opened = proc.open_files()
proc.kill()
for i in opened:
print(i.path)
io.FileIO(i.path).close()
print(io.FileIO(i.path).closed)
不知何故 io.IOBase(i.path).close() 不起作用。
解释:
这就像我想用 python 杀死 Microsoft Word,但它使一些文件保持打开状态。我也想关闭这些文件。
Microsoft Word 只是一个例子。这是一个自写的python程序。打开的文件是:
- 字体 (.ttf)
- clr.pyd
- 和.dll-s
我应该如何关闭这些文件?
请您参考如下方法:
您不需要关闭该进程打开的任何文件。完成automatically :
Terminating a process has the following results:
- Any remaining threads in the process are marked for termination.
- Any resources allocated by the process are freed.
- All kernel objects are closed.
- The process code is removed from memory.
- The process exit code is set.
- The process object is signaled.
重要的一点是“所有内核对象都已关闭”。对于每个打开的文件句柄,都有一个关联的内核对象——这实际上就是句柄,是从数字到内核对象的映射。当进程退出时,内核会走到后面并关闭所有关联的文件句柄、套接字等。
此外,您的原始方法存在一些问题。首先,打开文件列表只是当时打开文件的快照。在请求打开文件列表和终止进程之间,进程可能已经打开了更多文件,或者也关闭并删除了很多文件。其次,Python 3 文档说 IOBase 的构造函数不是公开的,因此以这种方式使用它是 wrong :
class io.IOBase
The abstract base class for all I/O classes, acting on streams of bytes. There is no public constructor.
通常,您会使用像 io.open() 这样的东西来获取路径。这就引出了第三个问题。您所要做的只是路径。为了关闭文件,您确实需要句柄。这些句柄是特定于流程的。这意味着在一个进程中,0x5555AAAA 可能对应于“file1.txt”,但在另一个进程中,它可能对应于“file2.txt”,甚至可能根本不是一个文件(它可能是一个套接字或其他东西)。所以即使你有内核句柄,我们也没有办法说“在这个其他进程的上下文中关闭这个句柄”。这违反了流程的一些安全目标。此外,这意味着您实际上在这里做的是创建您自己的句柄以仅转身并关闭它(或者在这种情况下,它可能什么都不做,因为对象没有正确创建)。
因此,如果您遇到文件仍被保留的问题,可能问题是在尝试完成您需要完成的任何工作之前,该进程实际上并未终止。如果您想要再次使用进程正在使用的文件,您可能需要等待进程退出才能继续。看起来您可以使用 psutils.wait_procs() 来做到这一点。
此外,我发现在 Windows 上,防病毒工具经常会妨碍工作。它们保存着应用程序访问的打开文件,这使得它看起来像是一个进程仍在保存它们,而实际上是病毒扫描程序在做它的事情。我记得在 Subversion 中必须处理这个问题的一个例子。代码仍然存在today .因此,您可能需要稍等片刻,然后重试。
更新
Microsoft Word is just an example. It is a self-written python programm. The opened files are:
- fonts (.ttf)
- clr.pyd
- and .dll-s
How should I close these files?
答案是您不需要这样做。只要确保该过程实际上已经退出即可。这不是即时操作,因此在杀死它和它实际退出之间有一段时间,它仍然保留文件句柄。
鉴于您实际上已经编写了被杀死的进程,我认为更好的方法是引入一种方法来启动该进程,让它完成工作,然后优雅地退出。然后使用 subprocess.run()运行脚本并等待它退出。
