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