Elenca i pacchetti e il loro stato

Domande sul packaging WAPT / Richieste e assistenza sui pacchetti Wapt.
Regole del forum
Regole del forum della community
* Supporto in inglese su www.reddit.com/r/wapt
* Supporto della community in francese disponibile su questo forum
* Si prega di anteporre [RISOLTO] al titolo dell'argomento se è stato risolto.
* Si prega di non modificare un argomento contrassegnato con [RISOLTO]. Aprire un nuovo argomento facendo riferimento a quello precedente.
* Specificare la versione di WAPT installata, la versione completa e il numero di build (2.2.1.11957 / 2.2.2.12337 / ecc.) nonché l'edizione Enterprise/Discovery.
* Le versioni 1.8.2 e precedenti non sono più supportate. Le uniche domande accettate relative alla versione 1.8.2 riguardano l'aggiornamento a una versione supportata (2.1, 2.2, ecc.).
* Specificare il sistema operativo del server (Linux/Windows) e la versione (Debian Buster/Bullseye - CentOS 7 - Windows Server 2012/2016/2019).
* Specificare il sistema operativo della macchina di amministrazione/creazione dei pacchetti e della macchina con l'agente problematico, se applicabile (Windows 7/10/11/Debian 11/ecc.).
* Evitare di porre più domande quando si apre una discussione, altrimenti potrebbe essere ignorata. Se ci sono più discussioni, aprirle separatamente, preferibilmente una dopo l'altra e non tutte contemporaneamente (ovvero, non intasare il forum).
* Includere frammenti di codice, screenshot e altre immagini direttamente nel post. I link a Pastebin, Bitly e altri siti di terze parti verranno sistematicamente rimossi.
* Come in qualsiasi forum della community, il supporto è fornito volontariamente dai membri. Se si necessita di supporto commerciale, è possibile contattare il reparto vendite di Tranquil IT al numero 02.40.97.57.55
Risposta
Mikael S
Messaggi: 22
Registrazione: 20 gennaio 2025 - 15:54

28 novembre 2025 - 11:19

Salve,

esiste un modo per elencare tutti i pacchetti installati su una macchina, insieme al loro stato e alla cronologia delle modifiche, da un file setup.py?

L'idea sarebbe quella di implementare una correzione automatica in alcuni casi di installazioni problematiche.



Cordiali saluti,
calvo
Messaggi: 18
Registrazione: 04/10/2025 - 22:59

2 dicembre 2025 - 7:18

Buongiorno,

Non sono del tutto sicuro di cosa stai cercando di fare, ma in uno dei miei pacchetti ho qualcosa del genere:

Codice: Seleziona tutto

package_list = WAPT.installed_package_names()      # recup les paquets installés sur la machine
for package in sorted(package_list):
    WAPT.audit(package, force=False)               # fait un audit du paquet pour chaque paquet présent dans la liste



Dopo tutto questo, è già visibile nella console WAPT.

Comandante.
WAPT Enterprise -- 2.6.1.17765 -- SRV Ubuntu 24.04 arm64
WAPT Enterprise -- 2.6.1.17705 -- SRV Ubuntu 22.04
WAPT Enterprise -- 2.6.1.17705 -- SRV RHEL 9 --//-- Repository secondari -- Rocky 9
Admin: W11pro
Mikael S
Messaggi: 22
Registrazione: 20 gennaio 2025 - 15:54

8 dicembre 2025 - 16:28

Salve,

questo non mi permette di ottenere lo stato.

L'idea è, ad esempio, che voglio installare Microsoft Visual C++ 2015-2022, ma poiché Windows è uno strumento così potente, l'installazione MSI richiede la disinstallazione della versione precedente, ma il file di installazione è stato eliminato.

Di conseguenza, il programma di installazione si blocca. È impossibile disinstallare, stesso problema, quindi devo cancellare il registro di sistema per far sì che Windows dimentichi la presenza di questa installazione e quindi eseguirne una nuova.
Questo tipo di situazione si verifica molto spesso con molti prodotti.

Creando un pacchetto di mediazione, elenco tutti gli errori presenti e avvio una procedura di correzione. In questo esempio, la cancellazione del registro di sistema consente un'installazione corretta.

Attualmente, eseguiamo questa operazione tramite console, manualmente. Ma con 10.000 workstation da gestire, di cui 450 con errori, la situazione diventa rapidamente insostenibile.
Utilizziamo di tutto, da KeePassXC, Seafile, Jabra, ecc.
Alcuni errori sono dovuti alla nostra soluzione precedente e non compaiono sulle macchine su cui è installato WAPT.

In breve, l'idea è di gestire tutto nel modo più automatico possibile, senza dover monitorare costantemente le macchine.
Tenete presente che una macchina riparata non significa che il problema non si ripresenterà con il prossimo aggiornamento. Dipende in gran parte dai programmi di installazione (spesso programmati in modo eccellente! :mrgreen: ).
florentR2
Messaggi: 100
Iscrizioni: 13 febbraio 2020 - ore 17:23

8 dicembre 2025 - 16:34

È molto interessante perché ho appena passato un bel po' di tempo a cercare una soluzione per il client Nextcloud che produce parecchi errori di questo tipo.
Ho sistemato questo pacchetto solo con i blocchi try-catch, ma la tua idea di un pacchetto di correzione generale non è male, mi iscriverò alla discussione se verrà fuori una soluzione.
Sto eliminando questo dal registro:

Codice: Seleziona tutto

HKLM\SOFTWARE\\Microsoft\Windows\CurrentVersion\Uninstall\{guid}
HKLM\SOFTWARE\Classes\Installer\Products\{guid_key_wininstaller}
calvo
Messaggi: 18
Registrazione: 04/10/2025 - 22:59

15 dicembre 2025 - 14:13

Buongiorno,

Per "stato" si intende se il pacchetto è in "OK"/"AVVERTENZA"/"ERRORE"?

Se è così, allora potresti provare questo:

Codice: Seleziona tutto

package = WAPT.is_installed('nom_de_votre_paquet')
package_status = package['install_status']                          # recupère si status OK/WARNING/ERROR
Una semplice istruzione di stampa dovrebbe visualizzare lo stato:

Codice: Seleziona tutto

print(package_status)
ma puoi poi fare, ad esempio, un

Codice: Seleziona tutto

if package_status == 'ERROR' : 
       ce que vous voulez faire ensuite



Modifica: ovviamente il pacchetto in questione deve essere già presente sulla macchina.
WAPT Enterprise -- 2.6.1.17765 -- SRV Ubuntu 24.04 arm64
WAPT Enterprise -- 2.6.1.17705 -- SRV Ubuntu 22.04
WAPT Enterprise -- 2.6.1.17705 -- SRV RHEL 9 --//-- Repository secondari -- Rocky 9
Admin: W11pro
Mikael S
Messaggi: 22
Registrazione: 20 gennaio 2025 - 15:54

3 febbraio 2026 - 13:24

Potrebbe esserci un modo più semplice, ma questo funziona per ottenere un elenco dei pacchetti la cui installazione non è riuscita.

Codice: Seleziona tutto

for package in WAPT.waptdb.installed_packages_inventory():
        if package[5] == 'ERROR':
            print(package[1])
Resta da provare a correggerlo, cercando di capire cosa correggere
Mikael S
Messaggi: 22
Registrazione: 20 gennaio 2025 - 15:54

16 marzo 2026 - 13:18

È ancora in fase di test, ma ecco come si presenta

Mantengo in memoria un file JSON contenente tutti i pacchetti inviati, in modo da effettuare un solo tentativo.

Finora, questo sta dando buoni risultati

Codice: Seleziona tutto

# -*- coding: utf-8 -*-
from setuphelpers import *
import json
import datetime
import winreg
import re
from contextlib import suppress
import itertools

# Dictionnaire package wapt => nom de l'application en format regex
dict_package_app = {
    "tis-chrome" : "Google Chrome",
    "tis-element" : "Element",
    "tis-googleearth" : "Google Earth Pro",
    "tis-glpi-agent" : "GLPI agent [0-9.]+",
    "tis-keepassxc" : "KeePassXC",
    "tis-libreoffice-fresh" : "LibreOffice [0-9.]+",
    "tis-microsoft-edge" : "Microsoft Edge",
    "tis-onlyoffice-desktop" : "ONLYOFFICE [0-9.]+ \(x64\)",
    "tis-oracle-java8-jre-free" : "Java 8 Update [0-9]+(| x64 bit)",
    "tis-pdf24-creator" : "PDF24 Creator",
    "tis-seafile" : "Seafile [0-9.]+",
    "tis-microsoft-teams" : "Teams Machine-Wide Installer",
    "tis-teamviewer" : "TeamViewer",
    "tis-vcredist2015-2022" : "Microsoft Visual C\+\+ (2015-2022 Redistributable \(x(86|64)\)|2022 X64 Additional Runtime) - [0-9.]+",
    "tis-wazo" : "Wazo Desktop",
    "tis-webex" : "Webex",
    "tis-webview2" : "Microsoft Edge WebView2 Runtime",
    "tis-zoom" : "Zoom Workplace \(64-bit\)"
}

json_file = r"C:\Windows\wapt\autofix.json"

def install():
    generate_json()

def audit():
    if not isfile(json_file):
        generate_json()

    with open(json_file) as file:
        status = json.load(file)

    return_value = "OK"
    packages_installed = set() # Contient la liste des paquets installés pour purge le json ensuite
    for wapt_installed_package in WAPT.waptdb.installed_status(include_errors=True):
        packages_installed.add(wapt_installed_package['package'])

        # Gestion des installation en erreur si le paquet est déclaré dans dict_package_app
        # Tentative de purge de la des anciennes installations de la base de registre
        if wapt_installed_package['install_status'] == "ERROR" and wapt_installed_package['package'] in dict_package_app:
            if status['install'].get(wapt_installed_package['package'], False):
                print(f"Réparation de l'installation du paquet {wapt_installed_package['package']} déjà tenté")
                return_value = "ERROR"
            else:
                print(f"Tentative de réparation de l'installation du paquet {wapt_installed_package['package']}")
                if WAPT.waptserver.available():
                    status['install'][wapt_installed_package['package']] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

                    delete_key("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 'DisplayName', dict_package_app[wapt_installed_package['package']])
                    delete_key("SOFTWARE\\Classes\\Installer\\Products", 'ProductName', dict_package_app[wapt_installed_package['package']])

                    try:
                        WAPT.install(wapt_installed_package['package'])
                    except:
                        print(f"Erreur d'installation de {wapt_installed_package['package']}")
                    if return_value != "ERROR":
                        return_value = "WARNING"
                else:
                    print("Serveur WAPT non joignable - une tentative sera faite au prochain audit")

        # Si le paquet n'est pas en erreur, on le retire du json s'il existe
        elif status['install'].get(wapt_installed_package['package'], False):
            del status['install'][wapt_installed_package['package']]

        # Gestion des audit en erreur
        # Tentative d'une installation forcée
        if wapt_installed_package['last_audit_status'] == "ERROR" and wapt_installed_package['package'] != "tis-autofix-installation":
            if status['audit'].get(wapt_installed_package['package'], False):
                print(f"Réparation de l'audit du paquet {wapt_installed_package['package']} déjà tenté")
                return_value = "ERROR"
            else:
                print(f"Tentative de réparation de l'audit du paquet {wapt_installed_package['package']}")
                if WAPT.waptserver.available():
                    status['audit'][wapt_installed_package['package']] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                    try:
                        WAPT.install(wapt_installed_package['package'], force=True)
                    except:
                        print(f"Erreur d'installation de {wapt_installed_package['package']}")

                    if return_value != "ERROR":
                        return_value = "WARNING"
                else:
                    print("Serveur WAPT non joignable - une tentative sera faite au prochain audit")

        # Si le paquet n'est pas en erreur, on le retire du json s'il existe
        elif status['audit'].get(wapt_installed_package['package'], False):
            del status['audit'][wapt_installed_package['package']]

    # Purge des anciennes tentative si le paquet n'est plus sur la machine
    for wapt_installed_package in status['install'].copy():
        if wapt_installed_package not in packages_installed:
            del  status['install'][wapt_installed_package]

    for wapt_installed_package in status['audit'].copy():
        if wapt_installed_package not in packages_installed:
            del status['audit'][wapt_installed_package]

    with open(json_file, 'w') as autofix:
        json.dump(status, autofix)

    return return_value

def uninstall():
    if isfile(json_file):
        remove_file(json_file)

def generate_json():
    if not isdir(r'C:\Windows\wapt'):
        mkdirs(r'C:\Windows\wapt')

    status = {}
    status['install'] = {}
    status['audit'] = {}

    with open(json_file, 'w') as autofix:
        json.dump(status, autofix)

def delete_key(key_uninstall, key_value, key_search):
    for subkey in subkeys(key_uninstall):
        appkey = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, rf"{key_uninstall}\{subkey}", 0, winreg.KEY_READ)
        try:
            key_find = reg_getvalue(appkey, key_value, '')

            if re.match(f"^{key_search}$", key_find):
                print(f'Suppression clé {key_uninstall}\{subkey}')
                winreg.DeleteKey(appkey, '')
        except FileNotFoundError:
            pass

def subkeys(path, hkey=HKEY_LOCAL_MACHINE):
    with suppress(WindowsError), winreg.OpenKey(hkey, path, 0, winreg.KEY_READ) as k:
        for i in itertools.count():
            yield winreg.EnumKey(k, i)
Ultima modifica di Mikael S il 24 marzo 2026 alle 07:59, modificato 1 volta.
florentR2
Messaggi: 100
Iscrizioni: 13 febbraio 2020 - ore 17:23

16 marzo 2026 - 13:58

Grazie per la condivisione!
Mikael S ha scritto: 16 marzo 2026 - 13:18 È ancora in fase di test, ma ecco come si presenta

Mantengo in memoria un file JSON contenente tutti i pacchetti inviati, in modo da effettuare un solo tentativo.

Finora, questo sta dando buoni risultati

Codice: Seleziona tutto

# -*- coding: utf-8 -*-
from setuphelpers import *
import json
import datetime
import winreg
import re

# Dictionnaire package wapt => nom de l'application en format regex
dict_package_app = {
    "tis-chrome" : "Google Chrome",
    "tis-element" : "Element",
    "tis-googleearth" : "Google Earth Pro",
    "tis-glpi-agent" : "GLPI agent [0-9.]+",
    "tis-keepassxc" : "KeePassXC",
    "tis-libreoffice-fresh" : "LibreOffice [0-9.]+",
    "tis-microsoft-edge" : "Microsoft Edge",
    "tis-oracle-java8-jre-free" : "Java 8 Update [0-9]+(| x64 bit)",
    "tis-pdf24-creator" : "PDF24 Creator",
    "tis-seafile" : "Seafile [0-9.]+",
    "tis-microsoft-teams" : "Teams Machine-Wide Installer",
    "tis-teamviewer" : "TeamViewer",
    "tis-vcredist2015-2022" : "Microsoft Visual C++ 2015-2022 Redistributable \(x(86|64)\) - [0-9.]+",
    "tis-wazo" : "Wazo Desktop",
    "tis-webex" : "Webex",
    "tis-webview2" : "Microsoft Edge WebView2 Runtime",
    "tis-zoom" : "Zoom Workplace \(64-bit\)"
}
json_file = r"C:\Windows\wapt\autofix.json"

def install():
    if not isfile(json_file) or force:
        generate_json()

def audit():
    if not isfile(json_file):
        generate_json()

    with open(json_file) as file:
        status = json.load(file)

    return_value = "OK"
    packages_installed = set() # Contient la liste des paquets installés pour purge le json ensuite
    for wapt_installed_package in WAPT.waptdb.installed_status(include_errors=True):
        packages_installed.add(wapt_installed_package['package'])

        # Gestion des installation en erreur si le paquet est déclaré dans dict_package_app
        # Tentative de purge de la des anciennes installations de la base de registre
        if wapt_installed_package['install_status'] == "ERROR" and wapt_installed_package['package'] in dict_package_app:
            if status['install'].get(wapt_installed_package['package'], False):
                print(f"Réparation de l'installation du paquet {wapt_installed_package['package']} déjà tenté")
                return_value = "ERROR"
            else:
                print(f"Tentative de réparation de l'installation du paquet {wapt_installed_package['package']}")
                if WAPT.waptserver.available():
                    status['install'][wapt_installed_package['package']] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

                    delete_key("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 'DisplayName', dict_package_app[wapt_installed_package['package']])
                    if iswin64():
                        delete_key("Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 'DisplayName', dict_package_app[wapt_installed_package['package']])

                    delete_key("SOFTWARE\\Classes\\Installer\\Products", 'ProductName', dict_package_app[wapt_installed_package['package']])

                    try:
                        WAPT.install(wapt_installed_package['package'])
                    except:
                        print(f"Erreur d'installation de {wapt_installed_package['package']}")
                    if return_value != "ERROR":
                        return_value = "WARNING"
                else:
                    print("Serveur WAPT non joignable - une tentative sera faite au prochain audit")

        # Si le paquet n'est pas en erreur, on le retire du json s'il existe
        elif status['install'].get(wapt_installed_package['package'], False):
            del status['install'][wapt_installed_package['package']]

        # Gestion des audit en erreur
        # Tentative d'une installation forcée
        if wapt_installed_package['last_audit_status'] == "ERROR" and wapt_installed_package['package'] != "tis-autofix-installation":
            if status['audit'].get(wapt_installed_package['package'], False):
                print(f"Réparation de l'audit du paquet {wapt_installed_package['package']} déjà tenté")
                return_value = "ERROR"
            else:
                print(f"Tentative de réparation de l'audit du paquet {wapt_installed_package['package']}")
                if WAPT.waptserver.available():
                    status['audit'][wapt_installed_package['package']] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                    try:
                        WAPT.install(wapt_installed_package['package'], force=True)
                    except:
                        print(f"Erreur d'installation de {wapt_installed_package['package']}")

                    if return_value != "ERROR":
                        return_value = "WARNING"
                else:
                    print("Serveur WAPT non joignable - une tentative sera faite au prochain audit")

        # Si le paquet n'est pas en erreur, on le retire du json s'il existe
        elif status['audit'].get(wapt_installed_package['package'], False):
            del status['audit'][wapt_installed_package['package']]

    # Purge des anciennes tentative si le paquet n'est plus sur la machine
    for wapt_installed_package in status['install'].copy():
        if wapt_installed_package not in packages_installed:
            del  status['install'][wapt_installed_package]

    for wapt_installed_package in status['audit'].copy():
        if wapt_installed_package not in packages_installed:
            del status['audit'][wapt_installed_package]

    with open(json_file, 'w') as autofix:
        json.dump(status, autofix)

    return return_value

def uninstall():
    if isfile(json_file):
        remove_file(json_file)


def generate_json():
    if not isdir(r'C:\Windows\wapt'):
        mkdirs(r'C:\Windows\wapt')

    status = {}
    status['install'] = {}
    status['audit'] = {}

    with open(json_file, 'w') as autofix:
        json.dump(status, autofix)

def delete_key(uninstall, key_value, key_search):
    with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, uninstall) as key:
        i = 0
        while True:
            try:
                subkey = winreg.EnumKey(key, i)
                appkey = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, "%s\\%s" % (uninstall, subkey))
                key_find = reg_getvalue(appkey, key_value, '')

                if re.match(f"^{key_search}$", key_find):
                    print(f'Suppression clé {uninstall}\{subkey}')
                    registry_deletekey(root=HKEY_LOCAL_MACHINE, path=uninstall, keyname=subkey, force=True, recursive=True)

                i += 1
            except WindowsError as e:
                # WindowsError: [Errno 259] No more data is available
                if e.winerror == 259:
                    break
                else:
                    raise
Mikael S
Messaggi: 22
Registrazione: 20 gennaio 2025 - 15:54

24 marzo 2026 - 08:00

Un breve aggiornamento con le ultime scoperte.
Risposta