Windows 환경에서 단순 반복 작업 프로그램들의 실행을 자동으로 컨트롤 하기 위함.
python 3.8.16
pywinauto 0.6.8
예시로 CUDA Toolkit 11.8.0 을 pywinauto를 이용해 자동으로 설치해볼 것이다.
먼저 아래 링크에서 CUDA 11.8.0를 다운로드 해야한다.
설치 관련해서 pywinauto의 함수만 궁금하신 분들은 install_packages.py
에서 install_Cuda
함수만 보시면 된다.
# install_packages.py
import os
import time
from pywinauto import application, keyboard
def load_installer(path, title = None):
app_backend = "uia" if os.path.splitext(path)[1] == ".exe" else "win32"
app = application.Application(backend = app_backend)
if os.path.splitext(path)[1] == ".bat":
os.system(path)
elif app_backend == "uia":
app.start(path, wait_for_idle = False)
elif app_backend :
app.start("msiexec.exe /i " + os.path.join(os.getcwd(), path), wait_for_idle = False)
time.sleep(2)
if title == "NVIDIA 설치 프로그램":
app["Dialog"].child_window(title = "OK", control_type = "Button").wait("enabled", timeout = 10).click()
installer = application.Application(backend = "uia").connect(title = title, timeout = 5)["Dialog"]
return installer
def report_install(idx, filepath, result:int, msg = None, process_type = "설치"):
if result == 1:
print(f"{idx}. {filepath} : {process_type} 완료.", flush = True)
elif result == 0:
print(f"{idx}. {filepath} : 이미 {process_type} 되어 있음.", flush = True)
elif result == -1:
print(f"{idx}. {filepath} : {process_type} 실패. message: {msg}", flush = True)
elif result == 2:
print(f"{idx}. {filepath} : 미{process_type}. message: {msg}", flush = True)
time.sleep(2)
def install_Cuda(idx, install_info:dict):
filepath = install_info["path"]; title = install_info["title"]
installer = load_installer(filepath, title)
installer.child_window(title="동의 및 계속(A)", control_type="Button").wait("enabled", timeout=600).click()
installer.child_window(title="다음(N)", control_type="Button").wait("enabled", timeout=10).click()
if installer.child_window(title = "I understand, and wish to continue the installation regardless.", control_type = "Button").exists(timeout = 2):
installer.child_window(title = "I understand, and wish to continue the installation regardless.", control_type = "Button").click()
keyboard.send_keys("n")
while True:
if installer.child_window(title="닫기(C)", control_type="Button").exists(timeout = 1):
if installer.child_window(title="바탕화면에 NVIDIA GeForce Experience 바로가기를 만듭니다", control_type="ListItem").exists():
installer.child_window(title="바탕화면에 NVIDIA GeForce Experience 바로가기를 만듭니다", control_type="ListItem").click_input(coords = (0, 0))
installer.child_window(title="NVIDIA GeForce Experience 시작", control_type="ListItem").click_input(coords = (0, 0))
installer.child_window(title="닫기(C)", control_type="Button").click()
report_install(idx, filepath, 1)
break
else:
installer.child_window(title="다음(N)", control_type="Button").wait("enabled", timeout=1800).click()
while True:
try:
installer.child_window(title="닫기(C)", control_type="Button").wait("enabled", timeout=1).click()
report_install(idx, filepath, 1)
break
except:
installer.child_window(title="다음(N)", control_type="Button").wait("enabled", timeout=1800).click()
# Autoinstaller.py
import os
from install_packages import *
import ctypes
install_info_dict = {
"CUDA": {"path": "cuda_11.8.0_522.06_windows.exe", "title": "NVIDIA 설치 프로그램"},
}
install_dict = {
"CUDA" : install_Cuda,
}
def main():
print("##### Auto-installer #####")
#관리자 권한 여부 확인
if bool(ctypes.windll.shell32.IsUserAnAdmin()) is False:
print("관리자 권한으로 실행하세요.")
return None
os.system("pause")
#Install
for idx, (key, func) in enumerate(install_dict.items(), start = 1):
try:
func(idx, install_info_dict[key])
except KeyboardInterrupt:
print("사용자 KeyboardInterrupt 설치 중단")
break
except:
report_install(idx, key, -1, '설치 에러')
print("\n 프로그램 설치 완료!")
if __name__ == "__main__":
main()
while True:
user_input = input("Enter q to quit: ")
if user_input.lower() == "q":
break