【问题标题】:How To Tell If A Program Is Open如何判断程序是否打开
【发布时间】:2019-01-27 02:29:09
【问题描述】:

我目前正在自动化一个涉及运行 Hapfacs 3.0 的过程,这是一个用于构建面部图像的 C# 程序。我正在使用python打开程序,设置一些参数,然后保存生成的图像。自动化将执行此过程 1000 次。保存过程包括打开文件资源管理器(我在 Windows 7 上),输入文件名,然后保存。

我遇到的一个问题是文件资源管理器有时需要一段时间才能打开,这会干扰自动化,因为程序在文件资源管理器窗口打开之前就开始输入文件名。

我想让程序在开始输入之前等待文件资源管理器打开。因此,我需要能够判断文件资源管理器是否打开。我在这里找到了这个页面:

Python check if a process is running or not

建议使用 psutil 模块:

import psutil    
"someProgram" in (p.name() for p in psutil.process_iter())

但是列表

[p.name() for p in psutil.process_iter()]

如果文件资源管理器打开与关闭时相比没有什么不同,这表明文件资源管理器从未添加到列表中。我仍然可以检查文件资源管理器是否已使用 psutil 打开,还是有其他方法可以实现我的目标?感谢您的帮助。

【问题讨论】:

  • 文件资源管理器几乎总是打开的。当您要求 Windows,例如,explore C:\Spamexplore.exe 程序启动,找到您现有的文件资源管理器进程,告诉它为 C:\Spam 打开一个窗口,然后退出。所以,完成之后,运行的进程集通常会和之前完全一样。
  • 那么如何判断文件资源管理器的窗口是否打开?无论文件资源管理器的窗口是否打开,[p.name() for p in psutil.process_iter()] 中的代码“explorer.exe”都会评估 True。
  • 如果 any 窗口打开?或者导航到某个特定目录的任何窗口?还是您可以通过某种方式识别但尚未解释的特定窗口?
  • 是的,当然是真的。正如我所说,文件资源管理器几乎总是打开的,所以几乎总是可以在 process_iter 中找到它。
  • 如果我能判断导航到特定目录的文件资源管理器窗口是否打开,那就可以了。

标签: python automation psutil


【解决方案1】:

不幸的是,你找不到任何改变的原因是在 Windows 上,负责几乎所有文件操作(文件资源管理器、桌面管理等)的“explorer.exe”始终处于打开状态,并且从单个实例运行。我不知道您可以通过 python 执行此操作的任何方式,但我确实有一个您可以合并的解决方案,即使它并不理想。

使用 PIL,在此处找到 http://www.pythonware.com/products/pil/,您可以抓取屏幕图像并检查特定点的像素颜色,这应该可以满足您当前的需求。如果您需要从屏幕上获取像素颜色,我能想到的用于快速模型的最佳工具是 autohotkeys window spy。

希望这会有所帮助,我知道有时当你不得不做这样的黑客攻击时自动化是多么烦人,所以如果你有任何其他问题,请告诉我。

编辑: 我的想法是当文件资源管理器打开时,资源管理器打开的句柄数量会增加相当大的幅度,如果你除了运行自动化脚本之外什么都不做,那么行为是相当的可预测,但需要您进行一些实验。

这就是我所拥有的:

import psutil
for proc in psutil.process_iter():
    if 'explorer' in proc.name():
        print(proc.name() + " handles:" + str(proc.num_handles()))

当我在文件资源管理器关闭和文件资源管理器打开的情况下运行此程序时,我会随机增加大约 100 个或更多句柄,因此您可以存储之前的数量并轮询当前数量假设您没有打开其他任何东西当句柄增加 X 数量时,您知道文件资源管理器已打开并可以开始输入,然后在接近 X 数量后,您知道它已关闭,您重新保存新的句柄计数并等待您的 X再次增加。

虽然这不是一个完美的解决方案,但您应该能够让它很好地满足您的需求。

编辑2

这对我有用,您可能需要更改通常的增加量,因为它可能是创建的句柄数量更多或更少。

import psutil
import time


handlesPrevious = 0
usualIncrease = 100

for proc in psutil.process_iter():
    if 'explorer' in proc.name():
        handlesPrevious = proc.num_handles()

while 1:
    time.sleep(5)
    for proc in psutil.process_iter():
        if 'explorer' in proc.name():
            handlesCurrent = proc.num_handles()
            if (handlesPrevious + usualIncrease) <= handlesCurrent:
                print("File explorer open! - handles:" + str(handlesCurrent) + " previous handles:" + str(handlesPrevious))
                handlesPrevious = handlesCurrent
            elif (handlesPrevious - usualIncrease) > handlesCurrent:
                print("File explorer not open! - handles:" + str(handlesCurrent))
                handlesPrevious = handlesCurrent

【讨论】:

  • 如何知道特定点的像素颜色会告诉您是否已打开某个资源管理器窗口(即使 OP 可以弄清楚如何定义他首先要查找的窗口) ?
  • 这只是基本的自动化,假设您的程序有一个文件浏览器屏幕和一个菜单屏幕,当您打开文件浏览器时,屏幕上许多位置的像素会发生变化,因为一个新窗口被放置在旧位置上,您只需选择任意位置。但无论如何,我已经用更好(更快)的解决方案更新了我的帖子。
  • @vividpk21 我比使用 PIL 更喜欢这个,因为 PIL 目前不支持 python 3+(我正在运行 python 3.6)。我会试试你的第二个建议,然后告诉你它是如何工作的。
  • @SpencerReschke Pillow 是 PIL 的现代版本,它确实支持 Python 3(事实上,它正在将 Python 2 转移到下一个版本中的旧支持)。
  • 我写了一个小测试,它可以工作,如果你想测试它,我用我的简单模型再次编辑了上面的内容。
【解决方案2】:

编辑:我觉得这是一个 XY 问题(http://xyproblem.info/),作者正在启动文件资源管理器并通过键盘选择 Hapfacs 文件,因为他们不知道如何使用命令行参数,“对于每个文件,启动Hapfacs.exe $file"。


也许您应该通过 Python 调用 Hapfacs,而不是尝试自动化文件资源管理器?

内置subprocess.Popen 可灵活用于管道。

subprocess.callplumbum 库更易于使用,如果您想调用程序并等待它终止。

【讨论】:

  • 调用一个程序并等待它终止在这里没有用,因为 explorer.exe 在告诉真正的 Explorer 进程打开一个新窗口后立即退出,这是 OP 试图解决的全部问题解决,而不是 OP 想要的,即使那不是真的,因为他们需要在窗口关闭之前与窗口进行交互。
  • 我觉得这是一个XY问题,作者正在启动文件资源管理器并通过键盘选择Hapfacs文件,因为他们不知道双击文件实际上是如何启动webbrowser.open(file)或@ 987654327@可以直接通过Python完成。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-05
  • 2010-10-20
  • 1970-01-01
  • 2012-05-22
  • 2023-04-06
相关资源
最近更新 更多