Page 2 sur 2

Re: Erreur Update package (1603)

Publié : 20 août 2025 - 00:41
par ddcorazon
(suite)

Une fois fini si tout s'est bien passé on a ça dans l'audit browser-msi-after-fix
Capture d'écran 2025-08-20 001828.png
Capture d'écran 2025-08-20 001828.png (42.03 Kio) Consulté 52 fois
Et normalement une fois fini je parviens à faire mes upgrade depuis wapt
Capture d’écran 2025-08-20 003943.png
Capture d’écran 2025-08-20 003943.png (58.23 Kio) Consulté 52 fois
J'ai quelques machines où ça n'a pas fonctionné (ça ne fonctionne pas sur les machines directement non plus même avec le bon msi de la bonne version)

Ci dessous le code (il est peut être plus optimisé j'avoue😅)

Code : Tout sélectionner

#Auteur ddcorazon
# -*- coding: utf-8 -*-
from setuphelpers import *
import os, glob, shutil, traceback

# === CONFIG ===
tools = ["chrome", "edge"]
AUDIT_SCOPE_BEFORE = "browser-msi"
AUDIT_SCOPE_AFTER  = "browser-msi-after-fix"

_UNINSTALL_KEYS = [
    r'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
    r'HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall',
    r'HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
    r'HKCU\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall',
]

def install():
    """Copie le dossier 'msi' du paquet vers persistent_dir\\msi pour l'audit."""
    src_dir = makepath(os.getcwd(), "msi")  # côté build/exec, cwd = racine du paquet
    dst_dir = makepath(persistent_dir, "msi")
    if os.path.isdir(src_dir):
        print("[INSTALL] Sync MSIs ->", dst_dir)
        if os.path.isdir(dst_dir):
            shutil.rmtree(dst_dir, ignore_errors=True)
        shutil.copytree(src_dir, dst_dir)
    else:
        print("[INSTALL] Aucun dossier 'msi' à copier (", src_dir, ")")

def uninstall():
    pass

# ----------------- Helpers -----------------
def _normalize_tools(t):
    if isinstance(t, (list, tuple)):
        lst = [str(x).strip() for x in t]
    else:
        lst = [s.strip() for s in str(t).split(",")]
    return [s.lower() for s in lst if s]

def _scan_registry(term):
    """Retourne (DisplayName, LocalPackagePath, DisplayVersion)."""
    for base in _UNINSTALL_KEYS:
        try:
            for sub in glob.glob(base + r'\*'):
                try:
                    dn = registry_readstring(sub, 'DisplayName', '')
                    if not dn or term not in dn.lower():
                        continue
                    lp = registry_readstring(sub, 'LocalPackage', '')
                    dv = registry_readstring(sub, 'DisplayVersion', '')
                    return ((dn or '').strip(), (lp or '').strip(), (dv or '').strip())
                except Exception:
                    continue
        except Exception:
            continue
    return (None, None, None)

def _scan_wmi(term):
    """Fallback WMI (Win32_Product)."""
    try:
        ps = (
            r"Get-WmiObject -Class Win32_Product | "
            r"Where-Object { $_.Name -ne $null -and $_.Name -like '*" + term + r"*' } | "
            r"Select-Object Name, LocalPackage, Version"
        )
        data = run_powershell(ps)
        if not data:
            return (None, None, None)
        row = data[0] if isinstance(data, list) else data
        name  = (row.get('Name') or '').strip()
        local = (row.get('LocalPackage') or '').strip()
        ver   = (row.get('Version') or '').strip()
        return (name or None, local or None, ver or None)
    except Exception:
        return (None, None, None)

def _detect_one(term):
    """Retourne (name, pkg_basename, version, file_flag)."""
    name, local, ver = _scan_registry(term)
    if not name and not local and not ver:
        name, local, ver = _scan_wmi(term)

    pkg = os.path.basename(local) if local else ""
    file_flag = "Unknown"
    if pkg:
        installer_dir = os.path.join(os.environ.get("SystemRoot", r"C:\Windows"), "Installer")
        candidate1 = os.path.join(installer_dir, pkg)
        candidate2 = local
        if (candidate2 and os.path.exists(candidate2)) or os.path.exists(candidate1):
            file_flag = "Found"
        else:
            file_flag = "Missing"

    return name or "", pkg, ver or "", file_flag

def _run_audit(scope):
    """Exécute l’audit pour tous les tools, retourne (result_data, found_any)."""
    result_data = {}
    found_any = False

    for term in _normalize_tools(tools):
        section = term.capitalize()
        name, pkg, ver, file_flag = _detect_one(term)

        result_data[section] = {
            "Name": name,
            "Package": pkg,
            "Version": ver,
            "File": file_flag
        }
        if name or pkg or ver:
            found_any = True

    WAPT.write_audit_data_if_changed(scope, "audit_data", result_data)
    WAPT.write_audit_data_if_changed(scope, "result", "OK" if found_any else "NotFound")
    return result_data, found_any

def _fix_missing(result_data):
    """
    Copie les MSI manquants depuis persistent_dir\\msi\\<tool>-<version>.msi
    -> C:\\Windows\\Installer\\<package>
    """
    installer_dir = os.path.join(os.environ.get("SystemRoot", r"C:\Windows"), "Installer")
    src_dir = makepath(persistent_dir, "msi")
    print(f"[INFO] Dossier source MSI: {src_dir}")

    for app, info in result_data.items():
        tool = app.lower()
        pkg  = info.get("Package")   # ex: 16af95e8.msi
        ver  = info.get("Version")   # ex: 139.0.x.x
        flag = info.get("File")

        if flag == "Missing" and pkg and ver:
            src = makepath(src_dir, f"{tool}-{ver}.msi")
            dst = makepath(installer_dir, pkg)
            if os.path.exists(src):
                print(f"[FIX] Copie {src} -> {dst}")
                os.makedirs(installer_dir, exist_ok=True)
                shutil.copyfile(src, dst)
            else:
                print(f"[WARN] MSI source introuvable pour {app}: {src}")

def _cleanup_persistent_msis():
    """Supprime persistent_dir\\msi pour ne rien laisser sur le poste."""
    msi_dir = makepath(persistent_dir, "msi")
    if os.path.isdir(msi_dir):
        print(f"[CLEANUP] Suppression du répertoire: {msi_dir}")
        shutil.rmtree(msi_dir, ignore_errors=True)

# ----------------- Audit principal -----------------
def audit():
    try:
        # 1) Audit avant
        before_data, found_any = _run_audit(AUDIT_SCOPE_BEFORE)

        # 2) Corrections si nécessaires
        if found_any:
            needs_fix = any(info.get("File") == "Missing" for info in before_data.values())
            if needs_fix:
                _fix_missing(before_data)
                # 3) Audit après correction
                _run_audit(AUDIT_SCOPE_AFTER)
            return "OK"
        else:
            return "NotFound"

    except Exception as e:
        print("[ERROR] Exception durant l'audit :", e)
        print(traceback.format_exc())
        return "ERROR"

    finally:
        # 4) Toujours nettoyer le persistent_dir\msi en fin d’audit
        _cleanup_persistent_msis()