#python-3.x #subprocess
#python-3.x #подпроцесс
Вопрос:
У меня есть код, который запускает файл Excel в графическом интерфейсе. Затем он обновляется пользователем и закрывается. Этот пользовательский ввод позже используется программой. Поэтому я хочу, чтобы моя программа ждала, пока пользователь не закроет файл Excel в графическом интерфейсе. Я попытался следовать, но, я думаю, он только ждет открытия программы.
import subprocess
loc = "C:\Users\Public\Documents\Sheet_groups.xlsx"
p = subprocess.Popen(['start',loc],stdout=subprocess.PIPE,shell = True)
p.communicate()
PS: я новичок в мире программирования
Ответ №1:
Вы можете использовать psutil (процессные и системные утилиты), чтобы проверить, открыт ли процесс Excel. Попробуйте это :
import psutil
import subprocess
import time
isopen=True
loc = "C:\Users\Public\Documents\Sheet_groups.xlsx"
p = subprocess.Popen(['start',loc],stdout=subprocess.PIPE,shell = True)
time.sleep(2)
while(isopen):
isopen="EXCEL.EXE" in (p.name() for p in psutil.process_iter())
time.sleep(2)
print("File closed")
Чтобы проверить, открыта ли конкретная windows, вы можете использовать библиотеку pywinauto, установив ее с помощью.
pip install pywinauto
Затем попробуйте :
import subprocess
import time
from pywinauto import Desktop
isopen=True
loc = "C:\Users\Public\Documents\Sheet_groups.xlsx"
p = subprocess.Popen(['start',loc],shell = True)
time.sleep(2)
windows = Desktop(backend="uia").windows()
while(isopen):
isopen="Sheet_groups.xlsx - Excel" in [w.window_text() for w in windows]
time.sleep(2)
print("File closed")
Вы можете попробовать это, если не можете использовать pywinauto:
import subprocess
import time
import win32gui
isopen=True
loc = "C:\Users\Public\Documents\Sheet_groups.xlsx"
running=""
def winEnumHandler( hwnd, ctx ):
global running
if win32gui.IsWindowVisible( hwnd ):
running =win32gui.GetWindowText( hwnd )
p = subprocess.Popen(['start',loc],shell = True)
time.sleep(2)
while(isopen):
isopen=win32gui.EnumWindows( winEnumHandler, None )
isopen="Sheet_groups.xlsx" in running
running=""
time.sleep(2)
print("File closed")
Комментарии:
1. Спасибо за ответ. Я получаю
psutil.AccessDenied: psutil.AccessDenied (pid=8)
, вероятно, потому, что я нахожусь на рабочем ноутбуке без прав администратора. В любом случае, не думаете ли вы, что ваше решение скажется на ресурсах процессора, если пользователь решит оставить Excel открытым надолго? @Fadi2. Да, вам нужны права администратора. Похоже, что он будет использовать много ресурсов процессора, если в цикле есть задержка, которая проверяет, открыт ли Excel. Итак, я исправил это, добавив задержку в 2 секунды.
3. Что делать, если у пользователя открыто несколько файлов Excel? Я думаю, в этом случае цикл останется открытым. Есть ли какой-нибудь чистый способ ожидания, например, с использованием потоков и очередей?
4. Да, цикл останется. Для решения этой проблемы вам понадобится другой подход.
5. Я добавил способ проверить, открыта ли определенная windows, но вам необходимо установить внешнюю библиотеку.