Inventario de software instalado (WMI)
Siguiendo con los ejempos y ahondando en las posibilidades de WMI (Windows Management Instrumentation), a raiz de este hilo en los foros del ClubDelphi, referente al software instalado en nuestro ordenador, he probado a obtener la lista de programas instalados utilizando la WMI.
Para ello podemos utilizar la clase Win32_Product.
Si accedemos a su descripción en MSDN, obtenemos la siguiente descripción de la clase:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | class Win32_Product : CIM_Product { uint16 AssignmentType; string Caption; string Description; string IdentifyingNumber; string InstallDate; datetime InstallDate2; string InstallLocation; sint16 InstallState; string HelpLink; string HelpTelephone; string InstallSource; string Language; string LocalPackage; string Name; string PackageCache; string PackageCode; string PackageName; string ProductID; string RegOwner; string RegCompany; string SKUNumber; string Transforms; string URLInfoAbout; string URLUpdateInfo; string Vendor; uint32 WordCount; string Version; }; |
Podemos disponer así de toda la información, referente a cada uno de los programas/aplicaciones instalados en nuestro equipo (*NOTA*).
Para ello, lo primero que debemos hacer es Importar a Delphi la librería “Microsoft WMI Scripting v1.X Library (Version 1.X)“, si no lo hemos hecho ya.
En la Introducción sobre WMI, se explica un poco más detalladamente.
Una vez importada, lo siguiente (dentro de nuestro ejemplo) es conectar con nuestro proveedor (en este caso nuestra máquina local):
1 2 3 4 5 6 | // Create the Location object Locator := CoSWbemLocator.Create(); // Connect to the WMI service, with the root\cimv2 namespace aServices := Locator.ConnectServer(STR_EMPTY, {Server} STR_CIM2_ROOT, {user}STR_EMPTY, {password}STR_EMPTY, STR_EMPTY,STR_EMPTY, 0, nil); |
A continuación, si la conexión ha sido correcta, realizamos la consulta sobre la clase Win32_Product, que nos dará la información que necesitamos.
1 2 3 | // realizar la consulta ObjSet := Services.ExecQuery('SELECT * FROM Win32_Product', 'WQL', wbemFlagReturnImmediately and wbemFlagForwardOnly , nil); |
A partir de ahí basta con recorrer los elementos obtenidos y e nuestro caso formatear algunas propiedades para mostrarlas (Caption, InstallDate, Vendor y Version), aunque todas las demás están igualmente a disponsición del programador.
Recordad de colocar en el USES las dos units comentadas antes.
Se puede descargar el código de ejemplo desde aquí y el ejecutable compilado desde aquí.
(*NOTA*): Recordemos (link), que una de las características de WMI es que permite «Administración remota», con lo que si tenemos los suficientes permisos, este código también puede servir para inventariar otras máquinas.
Embarcadero MVP.
Analista y Programador de Sistemas Informáticos.
Estudios de Informática (Ingeniería Técnica Superior) en la UPC (Universidad Politécnica de Barcelona).
Llevo utilizando Delphi desde su versión 3. Especialista en diseño de componentes, Bases de Datos, Frameworks de Persistencia, Integración Continua, Desarrollo móvil,…
Muchas gracias por la info, más una consulta, como puedo usarlo en lazarus.
@Tuxito
Hola Tuxito.
Siento no poder ayudarte en el tema de Lazarus.
No he trabajo con él y no se si es muy difícil traducir este código delphi a lazarus.
Busca ayuda sobre «WMI delphi code creator», es una utilidad que genera código lázarus. Si buscas esta clase, tal vez obtengas el código similar que necesitas.
Un saludo.
Buenas,
Me parece muy bueno como explicas en uso de esa clase. Además he visto los componentes que tienes con otras clases.
Primero que nada tengo que decirte que en los componentes GLibWMI el sitio web a la documentación de MSDN sobre Win32_Product ya no existe mas. Por otro lado quiero ver si conoces alguna otra forma de obtener estos datos ya que en muchos foros dicen que no hay uqe usarla porque es demaciada lenta la obtención de los aplicativos instalados, mas cuando se quieren traer de una máquina remota (este es el caso que yo necesito y además son muchas las que tengo que consultar).
He visto que algunos mensionan «W32Reg_AddRemovePrograms», pero como solo existe en el SCCM de Microsoft y no pertenece al estandar no se puede usar y no tiene documentación.
Saludos
Esta bueno el ejemplo para traer los datos del software instalado en otra computadora. Igualmente por lo que he leído en varios foros usar Win32_Product no es aconsejable porque es muy lento.
Mi pregunta es si no existe otra forma de traer todos esos datos sin hacer lento. Además he visto en el sitio MSDN que no le dan actualización a esta librería desde 2015, aunque al resto las vienen actualizando y hasta las cambiaron de sitio en un momento (Win32_Product es la única que sigue en el sitio viejo).
@Alejandro G.
Hola Alejandro. Si necesitas ayuda sobre una clase concreta, lo más sencillo es buscar en Google por WMI y el nombre de la clase; Por ejemplo «WMI Win32_Product» (sin las comillas) y el primer o segundo link te suele llevar a la ayuda de MSDN sobre esa clase.
En cuanto al uso de WMI, tiene sus ventajas y sus inconvenientes. Es cierto que es más lento que otros métodos, pero tiene la ventaja de que es estandard. Además para consulta de máquinas remotas, no tienes que hacer nada especial, ya que el código es el mismo.
No hay una opción genérica, para unos casos es mejor utilizar WMI, para otros un código específico.
@Alejandro G.
Que no hayan actualizado la clase, no quiere decir que no sea funcional al 100%.
Puedes intentar acceder al registro de windows para obtener la lista de programas instalados; Revisa la clave:
«SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall»
Eso tal vez te funcione para una máquina local y seguramente será más rápido, pero tendrás que ver cómo hacer eso y qué necesita para que funcione sobre máq. remotas.