Hola,
¿existe alguna forma de listar todos los paquetes instalados en una máquina, junto con su estado y registro de auditoría, desde un archivo setup.py?
La idea sería implementar la corrección automática en ciertos casos de instalaciones problemáticas.
Saludos,
Enumere los paquetes y su estado
Reglas del foro
Reglas del foro de la comunidad
* Soporte en inglés en www.reddit.com/r/wapt
* El soporte de la comunidad en francés está disponible en este foro
* Por favor, anteponga [RESUELTO] al título del tema si está resuelto.
* Por favor, no edite un tema que esté etiquetado como [RESUELTO]. Abra un nuevo tema haciendo referencia al anterior.
* Especifique la versión de WAPT instalada, la versión completa y el número de compilación (2.2.1.11957 / 2.2.2.12337 / etc.), así como la edición Enterprise/Discovery.
* Las versiones 1.8.2 y anteriores ya no son compatibles. Las únicas preguntas aceptadas sobre la versión 1.8.2 están relacionadas con la actualización a una versión compatible (2.1, 2.2, etc.).
* Especifique el sistema operativo del servidor (Linux/Windows) y la versión (Debian Buster/Bullseye - CentOS 7 - Windows Server 2012/2016/2019).
* Especifique el sistema operativo de la máquina de administración/creación de paquetes y de la máquina con el agente problemático, si corresponde (Windows 7/10/11/Debian 11/etc.).
* Evite hacer varias preguntas al abrir un tema, ya que podría ser ignorado. Si hay varios temas, ábralos por separado, preferiblemente uno tras otro y no todos a la vez (es decir, no sature el foro con spam).
* Incluya fragmentos de código, capturas de pantalla y otras imágenes directamente en la publicación. Los enlaces a Pastebin, Bitly y otros sitios de terceros serán eliminados sistemáticamente.
* Como en cualquier foro comunitario, el soporte es proporcionado voluntariamente por los miembros. Si necesita soporte comercial, puede comunicarse con el departamento de ventas de Tranquil IT al 02.40.97.57.55.
Reglas del foro de la comunidad
* Soporte en inglés en www.reddit.com/r/wapt
* El soporte de la comunidad en francés está disponible en este foro
* Por favor, anteponga [RESUELTO] al título del tema si está resuelto.
* Por favor, no edite un tema que esté etiquetado como [RESUELTO]. Abra un nuevo tema haciendo referencia al anterior.
* Especifique la versión de WAPT instalada, la versión completa y el número de compilación (2.2.1.11957 / 2.2.2.12337 / etc.), así como la edición Enterprise/Discovery.
* Las versiones 1.8.2 y anteriores ya no son compatibles. Las únicas preguntas aceptadas sobre la versión 1.8.2 están relacionadas con la actualización a una versión compatible (2.1, 2.2, etc.).
* Especifique el sistema operativo del servidor (Linux/Windows) y la versión (Debian Buster/Bullseye - CentOS 7 - Windows Server 2012/2016/2019).
* Especifique el sistema operativo de la máquina de administración/creación de paquetes y de la máquina con el agente problemático, si corresponde (Windows 7/10/11/Debian 11/etc.).
* Evite hacer varias preguntas al abrir un tema, ya que podría ser ignorado. Si hay varios temas, ábralos por separado, preferiblemente uno tras otro y no todos a la vez (es decir, no sature el foro con spam).
* Incluya fragmentos de código, capturas de pantalla y otras imágenes directamente en la publicación. Los enlaces a Pastebin, Bitly y otros sitios de terceros serán eliminados sistemáticamente.
* Como en cualquier foro comunitario, el soporte es proporcionado voluntariamente por los miembros. Si necesita soporte comercial, puede comunicarse con el departamento de ventas de Tranquil IT al 02.40.97.57.55.
Buen día,
No estoy completamente seguro de lo que estás intentando hacer, pero en uno de mis paquetes tengo algo como esto:
Después de todo esto, ya está visible en la consola WAPT.
Comandante.
No estoy completamente seguro de lo que estás intentando hacer, pero en uno de mis paquetes tengo algo como esto:
Código: Seleccionar todo
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 listeDespués de todo esto, ya está visible en la consola 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 --//-- Repositorios secundarios -- Rocky 9
Admin: W11pro
WAPT Enterprise -- 2.6.1.17705 -- SRV Ubuntu 22.04
WAPT Enterprise -- 2.6.1.17705 -- SRV RHEL 9 --//-- Repositorios secundarios -- Rocky 9
Admin: W11pro
Hola,
esto no me permite obtener el estado.
La idea es, por ejemplo, quiero instalar Microsoft Visual C++ 2015-2022, pero como Windows es una herramienta tan grande, la instalación MSI requiere desinstalar la anterior, pero el archivo de instalación ya se eliminó.
Por lo tanto, el instalador falla. Es imposible desinstalar, el mismo problema, así que tengo que limpiar el registro para que Windows olvide la presencia de esta instalación y así realizar una nueva.
Este tipo de situación ocurre muy a menudo con muchos productos.
Al crear un paquete de mediación, enumero todos los errores actuales y ejecuto una corrección. En este ejemplo, limpiar el registro permite una instalación exitosa.
Actualmente, tenemos esto en la consola y lo hacemos manualmente. Pero con 10,000 estaciones de trabajo que administrar, 450 de las cuales tienen errores, rápidamente se vuelve insostenible.
Tenemos de todo, desde KeePassXC, Seafile, Jabra, etc.
Algunos errores se deben a nuestra solución anterior y no aparecen en máquinas con WAPT instalado.
En resumen, la idea es gestionar todo de la forma más automática posible sin monitorizar constantemente los equipos.
Ten en cuenta que un equipo reparado no significa que el problema no vaya a reaparecer con la próxima actualización. Depende en gran medida de los instaladores (¡que suelen estar muy bien programados!
).
esto no me permite obtener el estado.
La idea es, por ejemplo, quiero instalar Microsoft Visual C++ 2015-2022, pero como Windows es una herramienta tan grande, la instalación MSI requiere desinstalar la anterior, pero el archivo de instalación ya se eliminó.
Por lo tanto, el instalador falla. Es imposible desinstalar, el mismo problema, así que tengo que limpiar el registro para que Windows olvide la presencia de esta instalación y así realizar una nueva.
Este tipo de situación ocurre muy a menudo con muchos productos.
Al crear un paquete de mediación, enumero todos los errores actuales y ejecuto una corrección. En este ejemplo, limpiar el registro permite una instalación exitosa.
Actualmente, tenemos esto en la consola y lo hacemos manualmente. Pero con 10,000 estaciones de trabajo que administrar, 450 de las cuales tienen errores, rápidamente se vuelve insostenible.
Tenemos de todo, desde KeePassXC, Seafile, Jabra, etc.
Algunos errores se deben a nuestra solución anterior y no aparecen en máquinas con WAPT instalado.
En resumen, la idea es gestionar todo de la forma más automática posible sin monitorizar constantemente los equipos.
Ten en cuenta que un equipo reparado no significa que el problema no vaya a reaparecer con la próxima actualización. Depende en gran medida de los instaladores (¡que suelen estar muy bien programados!
Esto es muy interesante porque acabo de pasar bastante tiempo intentando encontrar una solución para el cliente Nextcloud que está produciendo bastantes errores de este tipo.
Solo arreglé este paquete con bloques try catch, pero su idea de un paquete de remediación general no es mala, me suscribiré al tema si surge una solución.
Estoy purgando esto del registro:
Solo arreglé este paquete con bloques try catch, pero su idea de un paquete de remediación general no es mala, me suscribiré al tema si surge una solución.
Estoy purgando esto del registro:
Código: Seleccionar todo
HKLM\SOFTWARE\\Microsoft\Windows\CurrentVersion\Uninstall\{guid}
HKLM\SOFTWARE\Classes\Installer\Products\{guid_key_wininstaller}Buen día,
Por "estado", ¿se refiere a si el paquete está en "OK"/"ADVERTENCIA"/"ERROR"?
Si ese es el caso, entonces quizás puedas intentar esto:
Una simple declaración de impresión debería mostrar el estado:
pero luego puedes hacer, por ejemplo, un
Editar: Por supuesto, el paquete en cuestión ya debe estar presente en la máquina.
Por "estado", ¿se refiere a si el paquete está en "OK"/"ADVERTENCIA"/"ERROR"?
Si ese es el caso, entonces quizás puedas intentar esto:
Código: Seleccionar todo
package = WAPT.is_installed('nom_de_votre_paquet')
package_status = package['install_status'] # recupère si status OK/WARNING/ERRORCódigo: Seleccionar todo
print(package_status)Código: Seleccionar todo
if package_status == 'ERROR' :
ce que vous voulez faire ensuiteEditar: Por supuesto, el paquete en cuestión ya debe estar presente en la máquina.
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 --//-- Repositorios secundarios -- Rocky 9
Admin: W11pro
WAPT Enterprise -- 2.6.1.17705 -- SRV Ubuntu 22.04
WAPT Enterprise -- 2.6.1.17705 -- SRV RHEL 9 --//-- Repositorios secundarios -- Rocky 9
Admin: W11pro
Puede haber una forma más sencilla, pero ésta funciona para obtener una lista de paquetes cuya instalación falló.
Queda por intentar corregirlo, descubriendo qué hay que corregir
Código: Seleccionar todo
for package in WAPT.waptdb.installed_packages_inventory():
if package[5] == 'ERROR':
print(package[1])
Todavía se está probando aquí, pero este es su aspecto
Mantengo en memoria un archivo JSON con todos los paquetes que se han intentado transmitir, de modo que solo se realiza un intento.
Hasta ahora, esto está dando buenos resultados
Mantengo en memoria un archivo JSON con todos los paquetes que se han intentado transmitir, de modo que solo se realiza un intento.
Hasta ahora, esto está dando buenos resultados
Código: Seleccionar todo
# -*- 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)
Última edición realizada por Mikael S el 24 de marzo de 2026 a las 07:59; editado 1 vez.
¡Gracias por compartir!
Mikael S escribió: ↑16 de marzo de 2026 - 13:18 Todavía se está probando aquí, pero este es su aspecto
Mantengo en memoria un archivo JSON con todos los paquetes que se han intentado transmitir, de modo que solo se realiza un intento.
Hasta ahora, esto está dando buenos resultados
Código: Seleccionar todo
# -*- 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
