检查exe是否可运行/打开,并用python显示输出

检查exe是否可运行/打开,并用python显示输出,python,Python,所以我正在做一个python脚本作为我的学校项目,它试图一个接一个地运行exe。如果任何exe无法打开,则输出为“无法打开”,如果相反,则显示相反。 现在的问题是,即使脚本能够打开/运行exe,它也显示为不可打开,并且它唯一显示为打开的时间是我故意在一段时间后结束/终止exe(如果我立即结束它,则显示为不可打开)。如果我不终止打开的exe文件,它不会启动/运行其他exe。 所以我想要的是,如果脚本成功地打开了一个exe,那么脚本应该输出为“opened”,而不应该等待我终止它。 下面是有问题的代

所以我正在做一个python脚本作为我的学校项目,它试图一个接一个地运行exe。如果任何exe无法打开,则输出为“无法打开”,如果相反,则显示相反。 现在的问题是,即使脚本能够打开/运行exe,它也显示为不可打开,并且它唯一显示为打开的时间是我故意在一段时间后结束/终止exe(如果我立即结束它,则显示为不可打开)。如果我不终止打开的exe文件,它不会启动/运行其他exe。 所以我想要的是,如果脚本成功地打开了一个exe,那么脚本应该输出为“opened”,而不应该等待我终止它。 下面是有问题的代码`

 total = len(glob.glob("*.exe"))
notopened = 0
opened = 0
current = 0
print("opening exe's")
for fn in glob.glob("*.exe"):
    try:
            current += 1
            p = subprocess.Popen([fn])
            result = p.wait()
            if result == 1:
                    opened += 1
                
                print("[" + ("0" if current < 10 else "") + str(current) + "/" + str(total) + "]" + fn + " opened [" + str(round(((total - opened)/total) * 100, 2)) + "%]")
        else:
                  notopened += 1
                print("[" + ("0" if current < 10 else "") + str(current) + "/" + str(total) + "]" + fn + "   notopened [" + str(round(((total - opened)/total) * 100, 2)) + "%]")
except:
          notopened += 1
        print("[" + str(current) + "/" + str(total) + "] " + fn + "   notopened [" + str(round(((total - opened)/total) * 100, 2)) + "%]")
        pass
total=len(glob.glob(“*.exe”))
未开放=0
打开=0
电流=0
打印(“打开exe”)
对于glob.glob(“*.exe”)中的fn:
尝试:
电流+=1
p=子流程的Popen([fn])
结果=p.等待()
如果结果==1:
打开+=1
打印(“[”+(“0”如果当前值小于10,否则“)+str(当前值)+“/”+str(总计)+“]”“+fn+”打开[“+str(圆形)((总计打开)/总计)*100,2))+“%”)
其他:
未开放+=1
打印(“[”+(“0”如果当前值小于10,则为“其他”)+str(当前值)+“/”+str(总计值)+“]””+fn+“未打开”[“+str(圆形((总计-打开)/总计)*100,2))+“%]”)
除:
未开放+=1
打印(“[”+str(当前)+“/”+str(总计)+“]””+fn+“未打开[”+str(圆形)((总计-打开)/总计)*100,2))+“%]”)
通过

您可以使用
ThreadPoolExecutor
启动多个进程

下面是一个可能有帮助的代码。 请注意,我在这里使用了logger(顺便说一下,您需要将其配置为流式传输到控制台),因为日志记录是线程安全的,与打印不同

请注意,此代码不打印“opened”,我不知道如何在成功打开流程时执行此操作

import glob
import logging
import subprocess
from concurrent.futures import ThreadPoolExecutor, as_completed

logger = logging.getLogger(__name__)


def run_multiple_files(files):
    with ThreadPoolExecutor(max_workers=8) as executor:
        future_exec = {}
        for exe_file in files:
            future = executor.submit(run_one_file, exe_file)
            future_exec[future] = exe_file

        for future in as_completed(future_exec):
            exe_file = future_exec[future]
            try:
                future.result()
            except Exception as exc:
                logger.error(f'{exe_file} generated an exception: {exc}')


def run_one_file(exe_file):
    try:
        subprocess.run(
            [exe_file],
            stdout=subprocess.DEVNULL,
            stderr=subprocess.STDOUT,
            check=True,
        )
    except subprocess.CalledProcessError:
        msg = f'Failed {exe_file}'
        logger.error(msg)
        raise subprocess.CalledProcessError(msg)
    else:
        msg = f'Finished: {exe_file}'
        logger.info(msg)


if __name__ == '__main__':
    run_multiple_files(glob.glob('*.exe'))

wait
的结果是一个错误代码;零表示成功。你基本上颠倒了逻辑,把成功称为失败

此外,即使结果代码指示失败,也意味着进程实际运行。例如,在类Unix系统上,运行
false
命令时,根据设计,该命令将报告失败;缺少结果代码表示运行命令失败。在Python中,这将始终导致异常

另外,您可能应该避免使用
Popen
;正如
子流程
文档所述,在任何可以避免原始
Popen
的情况下,您都应该选择
运行
或其他更高级别的函数

另一方面,
打印
在所有情况下基本相同,只需重构即可在条件之外执行。我也清理了一下。你从来没有使用过
notopened
,所以我把它去掉了(这应该是
当前的
打开的
之间的区别)

files=glob.glob(“*.exe”)
总计=len(文件)
对于当前,枚举中的fn(文件,1):
尝试:
子进程运行([fn])
打开+=1
是否=“”
除例外情况外:
是否
打印([%02i/%i]%s%s%s已打印[%1.2f%%]”%(
当前,总计,fn,是否,100*(总开盘)/总计)

无论如何,随机打开可执行文件并等待它们完成是非常危险的。如果可执行文件格式化磁盘、关闭计算机或删除所有文件,该怎么办?您可能应该重新考虑您的方法。

请使用标准的python缩进4个空格或1个制表符,只缩进需要缩进的代码。很难读,我改了。现在可以了吗?您需要的可能是同时启动多个进程。我建议您查看
ThreadPoolExecutor
放弃子流程输出的好主意,但是
check=True
etc逻辑在这里也是错误的;请参阅我的答案以获得解释。实际上,根据问题标题,他们希望显示输出(我猜)。通过正确配置记录器,将显示输出。我指的是子流程的输出。标题上写着“打开并显示输出”,当然它们可能指的是自己脚本的输出。(为什么要将stderr重定向到stdout?)