Jump to content

Search registry for installed software


Recommended Posts

On 4/21/2017 at 2:59 PM, JLogan3o13 said:

I typically prefer WMI for this. You can do something as simple as:

$sName = InputBox("Installed Apps", "Please type the first few letters of the application name to search")
$oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
$aProducts = $oWMI.ExecQuery("Select * from Win32_Product Where Name LIKE '%" & $sName & "%'")

For $app in $aProducts
    ConsoleWrite($app.Name & @CRLF)
Next

If you do want to go Registry, this works just fine for me to list all of the keys. You should be able to modify it pretty easily:

 

Is there a smart way to put this in an array so I can reference it and see if a list of applications are installed?

I came up with this, but it feels crude.

;#RequireAdmin
#Include <Array.au3>

Global $aApps[500]
Global $i = 1

$oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
$aProducts = $oWMI.ExecQuery("Select * from Win32_Product")

For $app in $aProducts
    $aApps[$i] = $app.Name
    $i = $i+1
Next

$aApps[0] = $i
ReDim $aApps[$i]

_ArrayDisplay($aApps)

 

Link to comment
Share on other sites

  • Moderators

I would just do something like this:

#include <Array.au3>

Local $aApps[0]

$sName = InputBox("Installed Apps", "Please type the first few letters of the application name to search")
$oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
$aProducts = $oWMI.ExecQuery("Select * from Win32_Product Where Name LIKE '%" & $sName & "%'")

For $app in $aProducts
    _ArrayAdd($aApps, $app.Name)
Next

_ArrayDisplay($aApps)

You could add an initial index if you wanted to reference later on:

#include <Array.au3>

Local $aApps[1] = [""]

$sName = InputBox("Installed Apps", "Please type the first few letters of the application name to search")
$oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
$aProducts = $oWMI.ExecQuery("Select * from Win32_Product Where Name LIKE '%" & $sName & "%'")

For $app in $aProducts
    _ArrayAdd($aApps, $app.Name)
Next

$aApps[0] = UBound($aApps) - 1
_ArrayDisplay($aApps)

 

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Link to comment
Share on other sites

Figures the first piece of software I needed was not in WMI so had to fallback to Registry.

I normally use registry anyways and its faster so I guess thats fine.

I'll see if I can make the same kind of improvements you did on the WMI version for the Registry version.

;#RequireAdmin
#Include <Array.au3>

Global $sKeys
Global $sKeyPath = "HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
Global $aDisplayNames[500]
Global $sDisplayName
Global $iDisplayCount = 1
Global $iDebug = 0
If $CmdLine[0] > 0 Then $iDebug = $CmdLine[1]

For $i = 1 To 500
    $sKeys = RegEnumKey($sKeyPath, $i)
    If @error Then ExitLoop
    If $iDebug = 1 Then MsgBox(0, "", $sKeys)
    $sDisplayName = RegRead($sKeyPath & "\" & $sKeys, "DisplayName")
    If $sDisplayName <> "" Then
        $aDisplayNames[$iDisplayCount] = $sDisplayName
        $iDisplayCount +=1
    EndIf
Next

ReDim $aDisplayNames[$iDisplayCount]
$aDisplayNames[0] = $iDisplayCount

If $iDebug = 1 Then _ArrayDisplay($aDisplayNames)



;Reg HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ALOHA_is1      DisplayName   ALOHA Version 5.4.7

 

Here we go trimmed down a bit with your changes.

 

;#RequireAdmin
#Include <Array.au3>

Global $sKeys
Global $sKeyPath = "HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
Global $aDisplayNames[0]
Global $sDisplayName
Global $iDebug = 0
If $CmdLine[0] > 0 Then $iDebug = $CmdLine[1]

For $i = 1 To 500
    $sKeys = RegEnumKey($sKeyPath, $i)
    If @error Then ExitLoop
    If $iDebug = 1 Then MsgBox(0, "", $sKeys)
    $sDisplayName = RegRead($sKeyPath & "\" & $sKeys, "DisplayName")
    If $sDisplayName <> "" Then
        _ArrayAdd($aDisplayNames, $sDisplayName )
    EndIf
Next

$aDisplayNames[0] = UBound($aDisplayNames) -1

If $iDebug = 0 Then _ArrayDisplay($aDisplayNames)



;Reg HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ALOHA_is1      DisplayName   ALOHA Version 5.4.7

 

Edited by ViciousXUSMC
Link to comment
Share on other sites

You would need to add 1 row to $aDisplayNames[1] otherwise it will be overwriting your first entry, here is how I would do it to get both 32/64 bit entries

#include <Array.au3>

Global $iDebug = $CmdLine[0] > 1 ? True : False
Global $aDisplayName[1][2]
Global $sRegPathx86 = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"
Global $sRegPathx64 = "HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"

_RegSearch($sRegPathx86)
_RegSearch($sRegPathx64)

_ArrayDisplay($aDisplayName)

Func _RegSearch($sRegPath)
    Local $sSubKey = "", $i = 1, $sDisplayName
    While 1
        $sSubKey = RegEnumKey($sRegPath, $i)
            If @error Then ExitLoop
        If $iDebug = 1 Then MsgBox(4096, "SubKey", $sSubKey)
        $sDisplayName = RegRead($sRegPath & $sSubKey, "DisplayName")
        If $sDisplayName <> "" Then _ArrayAdd($aDisplayName, $sRegPath & $sSubKey & "|" & $sDisplayName)
        $i += 1
    WEnd
    $aDisplayName[0][0] = UBound($aDisplayName) - 1
EndFunc

 

Link to comment
Share on other sites

Thanks I got it, noticed it as I was working on the rest of things.

Sorry for OP if I derailed your thread any, figured it was relevant to the same topic. 

Got my full script up today and tested it as working 100%

Free software for Chemicals/Hazmat just by the off chance anybody else uses it lol.

 

#RequireAdmin
#Include <Array.au3>

Global $sFile
Global $sKeys
Global $sKeyPath = "HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
Global $aDisplayNames[1]
Global $sDisplayName
Global $sProgramFiles = "Program Files (x86)"
If StringInStr(@OSArch, "86") Then $sProgramFiles = "Program Files"
Global $iDebug = 0
Global $iUninstall = 0
If $CmdLine[0] > 0 Then
    For $i = 1 To $CmdLine[0]
        If StringInStr($CmdLine[$i], "debug") Then $iDebug = 1
        If StringInStr($CmdLine[$i], "remove") Then $iUninstall = 1
    Next
EndIf

For $i = 1 To 500
    $sKeys = RegEnumKey($sKeyPath, $i)
    If @error Then ExitLoop
    If $iDebug = 1 Then MsgBox(0, "", $sKeys)
    $sDisplayName = RegRead($sKeyPath & "\" & $sKeys, "DisplayName")
    If $sDisplayName <> "" Then
        _ArrayAdd($aDisplayNames, $sDisplayName )
    EndIf
Next

$aDisplayNames[0] = UBound($aDisplayNames) -1

If $iDebug = 1 Then _ArrayDisplay($aDisplayNames)

If _Arraysearch($aDisplayNames, "ALOHA", 1, 0, 0, 3) = -1 Then _InstallAloha()
If _Arraysearch($aDisplayNames, "CAMEO Chemicals", 1, 0, 0, 3) = -1 Then _InstallChemicals()
If _Arraysearch($aDisplayNames, "CAMEO Version", 1, 0, 0, 3) = -1 Then _InstallCameoFM()
If _Arraysearch($aDisplayNames, "ERG", 1, 0, 0, 3) = -1 Then _InstallERG()
If _Arraysearch($aDisplayNames, "MARPLOT", 1, 0, 0, 3) = -1 Then _InstallMarplot()
If _Arraysearch($aDisplayNames, "WISER", 1, 0, 0, 3) = -1 Then _InstallWiser()
If Not FileExists("C:\NIOSH Pocket Guide") Then _InstallNiosh()

If $iUninstall = 1 Then
    _InstallAloha()
    _InstallChemicals()
    _InstallCameoFM()
    _InstallERG()
    _InstallMarplot()
    _InstallWiser()
    _InstallNiosh()
EndIf

Func _InstallAloha()
    If $iUninstall = 1 Then
        $sFile = "C:\" & $sProgramFiles & "\ALOHA\unins000.exe"
        If FileExists($sFile) Then ShellExecuteWait($sFile, "/VERYSILENT", "", "", @SW_HIDE)
        FileDelete(@DesktopCommonDir & "\Aloha.lnk")
        Return
    EndIf
    ShellExecuteWait("SilentInstall.bat", "", @ScriptDir & "\Aloha", "", @SW_HIDE)
    FileCreateShortcut("C:\" & $sProgramFiles & "\ALOHA\ALOHA.EXE", @DesktopCommonDir & "\Aloha.lnk")
EndFunc ;End _InstallAloha

Func _InstallChemicals()
    If $iUninstall = 1 Then
        $sFile = "C:\" & $sProgramFiles & "\CAMEO Chemicals\unins000.exe"
        If FileExists($sFile) Then ShellExecuteWait($sFile, "/VERYSILENT", "", "", @SW_HIDE)
        FileDelete(@DesktopCommonDir & "\Cameo Chemicals.lnk")
        Return
    EndIf
    ShellExecuteWait("SilentInstall.bat", "", @ScriptDir & "\Cameo Chemicals", "", @SW_HIDE)
    FileCreateShortcut("C:\" & $sProgramFiles & "\CAMEO Chemicals\CAMEOChemicals.exe", @DesktopCommonDir & "\Cameo Chemicals.lnk")
EndFunc ;End _InstallChemicals

Func _InstallCameoFM()
    If $iUninstall = 1 Then
        $sFile = "C:\" & $sProgramFiles & "\CAMEO\unins000.exe"
        If FileExists($sFile) Then ShellExecuteWait($sFile, "/VERYSILENT", "", "", @SW_HIDE)
        FileDelete(@DesktopCommonDir & "\Cameo FM.lnk")
        Return
    EndIf
    ShellExecuteWait("SilentInstall.bat", "", @ScriptDir & "\CameoFM", "", @SW_HIDE)
    FileCreateShortcut("C:\" & $sProgramFiles & "\CAMEO\CAMEOfm.exe", @DesktopCommonDir & "\Cameo FM.lnk")
EndFunc ;End _InstallCameoFM

Func _InstallMarplot()
    If $iUninstall = 1 Then
        $sFile = "C:\" & $sProgramFiles & "\MARPLOT\unins000.exe"
        If FileExists($sFile) Then ShellExecuteWait($sFile, "/VERYSILENT", "", "", @SW_HIDE)
        Return
    EndIf
    ShellExecuteWait("SilentInstall.bat", "", @ScriptDir & "\Marplot", "", @SW_HIDE)
EndFunc ;End _InstallMarplot

Func _InstallERG()
    If $iUninstall = 1 Then
        $sFile = "C:\" & $sProgramFiles & "\DOT ERG 2016\Windows\unins000.exe"
        If FileExists($sFile) Then ShellExecuteWait($sFile, "/VERYSILENT", "", "", @SW_HIDE)
        Return
    EndIf
    ShellExecuteWait("SilentInstall.bat", "", @ScriptDir & "\ERG", "", @SW_HIDE)
EndFunc ;End _InstallERG

Func _InstallWiser()
    If $iUninstall = 1 Then
        $sFile = "C:\" & $sProgramFiles & "\WISER\Windows\unins000.exe"
        If FileExists($sFile) Then ShellExecuteWait($sFile, "/VERYSILENT", "", "", @SW_HIDE)
        Return
    EndIf
    ShellExecuteWait("SilentInstall.bat", "", @ScriptDir & "\Wiser", "", @SW_HIDE)
EndFunc ;End _InstallWiser

Func _InstallNiosh()
    If $iUninstall = 1 Then
        DirRemove("C:\NIOSH Pocket Guide", 1)
        FileDelete(@DesktopCommonDir & "\NIOSH Pocket Guide.lnk")
        Return
    EndIf
    ShellExecuteWait("SilentInstall.bat", "", @ScriptDir & "\NIOSH Pocket Guide", "", @SW_HIDE)
    FileCreateShortcut("C:\NIOSH Pocket Guide\start.htm", @DesktopCommonDir & "\NIOSH Pocket Guide.lnk")
EndFunc ;End _InstallNiosh

#Region Registry Entries
;Reg HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ALOHA_is1
;   DisplayName ALOHA Version 5.4.7
;   UninstallString "C:\Program Files (x86)\ALOHA\unins000.exe"
;   QuietUninstallString    "C:\Program Files (x86)\ALOHA\unins000.exe" /SILENT
;Reg HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\CAMEO Chemicals_is1
;   DisplayName CAMEO Chemicals 2.7
;   UninstallString "C:\Program Files (x86)\CAMEO Chemicals\unins000.exe"
;   QuietUninstallString "C:\Program Files (x86)\CAMEO Chemicals\unins000.exe" /SILENT
;Reg HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\CAMEO_is1
;   DisplayName CAMEO Version 3.3
;   UninstallString "C:\Program Files (x86)\CAMEO\unins000.exe"
;   QuietUninstallString    "C:\Program Files (x86)\CAMEO\unins000.exe" /SILENT
;Reg HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ERG 2016 for Windows_is1
;   DisplayName ERG 2016 for Windows (version 4.0)
;   UninstallString "C:\Program Files (x86)\DOT ERG 2016\Windows\unins000.exe"
;   QuietUninstallString    "C:\Program Files (x86)\DOT ERG 2016\Windows\unins000.exe" /SILENT
;Reg HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\MARPLOT_is1
;   DisplayName MARPLOT Version 5.0.3
;   UninstallString "C:\Program Files (x86)\MARPLOT\unins000.exe"
;   QuietUninstallString    "C:\Program Files (x86)\MARPLOT\unins000.exe" /SILENT
;Reg HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\WISER for Windows_is1
;   DisplayName WISER 5.0 for Windows
;   UninstallString "C:\Program Files (x86)\WISER\Windows\unins000.exe"
;   QuietUninstallString    "C:\Program Files (x86)\WISER\Windows\unins000.exe" /SILENT
#EndRegion Registry Entries

 

Link to comment
Share on other sites

1 hour ago, Subz said:

Since a number are InnoSetup scripts wouldn't be better to get UninstallString in case the user has installed to a different folder?

Yes, it would be wise should that be needed.

However I am the only person that installs it so it's always in the default location.

Our users can not install anything as they are not admins :)

Link to comment
Share on other sites

  • 11 months later...

Hi,

I do it with InnoSetup  when i generate a Windows Setup.

To do this, it is based on the GUID (global unique identifier) defined in the InnoSetup script. It is important not to change the code between different application versions and that it is unique. The IDE provided by InnoSetup provides a tool to generate a new one accessible via the menu: Tools> Generate GUID inside the IDE.

; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
#define ApplicationGUID "1234687ZE-AAB5-48766-BCD5-FERZAERDS"
#define ApplicationID ApplicationName + "_" + ApplicationGUID

In addition, the installer adds the SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{#ApplicationID}_is1 key into the Windows registry. When the application is uninstalled, this key is removed. So we just have to check the presence of this key in the registry to know if the application has already been installed.

And i add in the

section of ISS script this :



[Code]
function InitializeSetup(): Boolean;
var
  ResultCode: Integer;
  ResultStr:string;
begin
  // Check if the application is already install
  // MsgBox('ApplicationID = ' + '{#ApplicationID}', mbInformation, mb_Ok);
  begin
    If RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{#ApplicationID}_is1', 'UninstallString', ResultStr) then begin
      If ResultStr<>'' then begin
        ResultStr:=RemoveQuotes(ResultStr);
          if MsgBox('{#ApplicationName} ' + ExpandConstant('{cm:CheckInstall}') + #13#13 + ExpandConstant('{cm:CheckInstallAction}'), mbConfirmation, MB_YESNO) = idYes then
          if not Exec(ResultStr, '/silent', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then
            MsgBox('Erreur !!! ' #13#13 '' + SysErrorMessage(ResultCode) + '.', mbError, MB_OK);
      end;
    end;
  end ;
  Result := True;
end;

(...)

(extract from : https://github.com/v20100v/autoit-gui-skeleton/blob/master/source/deployment/deployment_autoit_application.iss)

++

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...