feat(core): rewrite installer with modular config, dynamic drive resolver, and clean orchestration

This commit is contained in:
2026-09-01 17:04:16 +03:30
parent ce34e66154
commit 30abb98928
6 changed files with 418 additions and 155 deletions

View File

@@ -1,71 +1,107 @@
"""
Extractor and automated installer runner for NovinDesk.
"""
import logging
import os
import zipfile
from pathlib import Path
import subprocess
import time
from typing import Optional
import zipfile
def install_novindesk(base_drive: str = r"D:\\") -> str:
from module.config import InstallerConfig, detect_target_drive
logger = logging.getLogger("acc_installer")
def automate_installer_dialog() -> bool:
"""
Extract and automatically install NovinDesk by navigating the installer UI.
Automate UI dialog clicks for silent installation using pyautogui.
"""
base_dir = os.path.join(base_drive, "NovinPardazOne")
soft_dir = os.path.join(base_dir, "NovinSoft")
zip_filename = "NovinDesk.zip"
source_zip_path = os.path.join(soft_dir, zip_filename)
extract_target_dir = os.path.join(soft_dir, "NovinDesk")
if not os.path.exists(source_zip_path):
raise FileNotFoundError(f"[-] File {zip_filename} was not found in {soft_dir}!")
os.makedirs(extract_target_dir, exist_ok=True)
print(f"[+] Extracting {zip_filename} ...")
with zipfile.ZipFile(source_zip_path, 'r') as zip_ref:
zip_ref.extractall(extract_target_dir)
print(" [+] Extraction completed successfully.")
exe_file = None
for root, dirs, files in os.walk(extract_target_dir):
for file in files:
if file.lower().endswith(".exe"):
exe_file = os.path.join(root, file)
break
if not exe_file:
raise FileNotFoundError("[-] No executable file (.exe) found!")
print(f"[+] Launching installer {os.path.basename(exe_file)} ...")
# Launch application for installation
subprocess.Popen([exe_file, "--install"])
# Wait 5 seconds for the window to fully load
time.sleep(5)
try:
import pyautogui
import pyautogui # type: ignore
# 1. Close any secondary/side dialogs
pyautogui.press('escape')
time.sleep(0.5)
# 2. Press Tab 4 times to navigate directly to the 'Accept & Install' button
# 2. Press Tab 4 times to navigate directly to 'Accept & Install'
for _ in range(4):
pyautogui.press('tab')
time.sleep(0.2)
# 3. Press Enter on the install button
pyautogui.press('enter')
print(" [+] Confirmation sent and automated installation started.")
print(" [+] Sent automated UI confirmation successfully.")
return True
except ImportError:
print(" [!] Warning: 'pyautogui' is not installed. Skipping UI automation.")
return False
except Exception as err:
print(f" [-] Automation error: {err}")
print(f" [-] UI Automation error: {err}")
return False
def install_novindesk(config: Optional[InstallerConfig] = None,
archive_name: str = "NovinDesk.zip",
auto_ui: bool = True) -> Path:
"""
Extracts NovinDesk archive, finds the installer executable, and runs installation.
"""
if config is None:
config = InstallerConfig()
source_zip = config.soft_dir / archive_name
extract_target_dir = config.soft_dir / "NovinDesk"
if config.dry_run:
print(f" [DRY-RUN] Would locate {archive_name}, extract into {extract_target_dir}, and launch installer.")
return extract_target_dir
if not source_zip.exists() and not extract_target_dir.exists():
raise FileNotFoundError(f"Neither '{source_zip}' nor '{extract_target_dir}' exists!")
# Extract archive if needed
if source_zip.exists():
extract_target_dir.mkdir(parents=True, exist_ok=True)
print(f"[+] Extracting {archive_name} into {extract_target_dir} ...")
with zipfile.ZipFile(source_zip, 'r') as zip_ref:
zip_ref.extractall(extract_target_dir)
print(" [+] Extraction completed successfully.")
# Locate executable
exe_file = None
for root, _, files in os.walk(extract_target_dir):
for file in files:
if file.lower().endswith(".exe"):
exe_file = Path(root) / file
break
if exe_file:
break
if not exe_file:
raise FileNotFoundError(f"No executable (.exe) found in {extract_target_dir}!")
print(f"[+] Launching installer {exe_file.name} ...")
subprocess.Popen([str(exe_file), "--install"])
if auto_ui:
print(" [*] Waiting 5 seconds for installer window to initialize...")
time.sleep(5)
automate_installer_dialog()
return exe_file
if __name__ == "__main__":
os.system("chcp 65001 > nul")
print("[+] Running NovinDesk installation module ...")
import sys
logging.basicConfig(level=logging.INFO, format="%(message)s")
print("[*] Running NovinDesk installation module standalone ...")
try:
install_novindesk(base_drive=r"D:\\")
cfg = InstallerConfig(target_drive=detect_target_drive())
install_novindesk(cfg)
print("[+] NovinDesk installation module completed successfully.")
except Exception as e:
print(f"[-] Error: {e}")
print(f"[-] Error: {e}", file=sys.stderr)
sys.exit(1)