Sign in to follow this  
Followers 0
jguinch

_UninstallList : List/Search uninstall keys from registry

14 posts in this topic

#1 ·  Posted (edited)

Here is a small function that lists installed applications from the registry (uninstall keys). _UninstallList() allows to search on specific string in registry values.
The feature supports x86 and x64, even if the program is compiled in 32 or 64 bits.

Thanks for you comments and suggestions.

! NEW VERSION !

Changes :

 - The function returns the installation date of each application (see remark)

 - $sCol parameter added : allows you to add columns in the returned array

Remark : the installation date is retrieved from the InstallDate value in the registry. If this value does not exist, the InstallDate takes the last time at which the subkey was last written (great idea from JFX, thanks to him !)

#include <Date.au3> ; needed for _UninstallList function



; Examples ##########################################################################################################
#Include <Array.au3> ; Just for _ArrayDisplay
Local $aList

; Lists all uninstall keys
$aList = _UninstallList()
_ArrayDisplay($aList, "All uninstall keys", Default, Default, Default, "RegistryPath|RegistrySubKey|DisplayName|Date")

; Lists all keys, where the publisher name (Publisher value) starts with "adobe"
$aList = _UninstallList("Publisher", "Adobe")
_ArrayDisplay($aList, "Adobe Publisher", Default, Default, Default, "RegistryPath|RegistrySubKey|DisplayName|Date")

; Lists all x86 keys only, where the name (DisplayName value) contains "flash"
$aList = _UninstallList("DisplayName", "Flash", "", 1, 1)
_ArrayDisplay($aList, "Flash (x86)", Default, Default, Default, "RegistryPath|RegistrySubKey|DisplayName|Date")

; Lists all keys matching a Java version (using a regular expression)
$aList = _UninstallList("DisplayName", "(?i)Java \d+ Update \d+", "", 3)
_ArrayDisplay($aList, "Java", Default, Default, Default, "RegistryPath|RegistrySubKey|DisplayName|Date")

; Lists all x64 keys only, where the quiet uninstall string (QuietUninstallString value) is set
$aList = _UninstallList("QuietUninstallString", ".+", "QuietUninstallString", 3, 2)
_ArrayDisplay($aList, "QuietUninstallString (x64)", Default, Default, Default, "RegistryPath|RegistrySubKey|DisplayName|Date|QuietUninstallString")

; List all x86 keys only, where the name (DisplayName value) start with "Autoit"  and retrieve the
; UninstallString, DisplayVersion values
$aList = _UninstallList("DisplayName", "Autoit", "UninstallString|DisplayVersion", 0, 1)
_ArrayDisplay($aList, "Autoit (x86)", Default, Default, Default, "RegistryPath|RegistrySubKey|DisplayName|Date|UninstallString|DisplayVersion")
; ###################################################################################################################




; #FUNCTION# ====================================================================================================================
; Name ..........: _UninstallList
; Description ...: Returns an array of matching uninstall keys from registry, with an optional filter
; Syntax ........: _UninstallList([$sValueName = ""[, $sFilter = ""[, $sCols = ""[, $iSearchMode = 0[,$ iArch = 3]]]]]])
; Parameters ....: $sValueName       - [optional] Registry value used for the filter.
;                                          Default is all keys ($sFilter do not operates).
;                  $sFilter          - [optional] String to search in $sValueName. Filter is not case sensitive.
;                  $sCols            - [optional] Additional values to retrieve. Use "|" to separate each value.
;                                          Each value adds a column in the returned array
;                  $iSearchMode      - [optional] Search mode. Default is 0.
;                                          0 : Match string from the start.
;                                          1 : Match any substring.
;                                          2 : Exact string match.
;                                          3 : $sFilter is a regular expression
;                  $iArch            - [optional] Registry keys to search in. Default is 3.
;                                          1 : x86 registry keys only
;                                          2 : x64 registry keys only
;                                          3 : both x86 and x64 registry keys
; Return values .: Returns a 2D array of registry keys and values :
;                      $array[0][0] : Number of keys
;                      $array[n][0] : Registry key path
;                      $array[n][1] : Registry subkey
;                      $array[n][2] : Display name
;                      $array[n][3] : Installation date (YYYYMMDD format)
;                      $array[n][4] : 1st additional value specified in $sCols (only if $sCols is set)
;                      $array[n][5] : 2nd additional value specified in $sCols (only if $sCols contains at least 2 entries)
;                      $array[n][x] : Nth additional value ...
; Author ........: jguinch
; ===============================================================================================================================
Func _UninstallList($sValueName = "", $sFilter = "", $sCols = "", $iSearchMode = 0, $iArch = 3)
    Local $sHKLMx86, $sHKLM64, $sHKCU = "HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall"
    Local $aKeys[1] = [ $sHKCU ]
    Local $sDisplayName, $sSubKey, $sKeyDate, $sDate, $sValue, $iFound, $n, $aResult[1][4], $iCol
    Local $aCols[1] = [0]

    If NOT IsInt($iArch) OR $iArch < 0 OR $iArch > 3 Then Return SetError(1, 0, 0)
    If NOT IsInt($iSearchMode) OR $iSearchMode < 0 OR $iSearchMode > 3 Then Return SetError(1, 0, 0)

    $sCols = StringRegExpReplace( StringRegExpReplace($sCols, "(?i)(DisplayName|InstallDate)\|?", ""), "\|$", "")
    If $sCols <> "" Then $aCols = StringSplit($sCols, "|")

    If @OSArch = "X86" Then
        $iArch = 1
        $sHKLMx86 = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
    Else
        If @AutoitX64 Then
            $sHKLMx86 = "HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
            $sHKLM64 = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
        Else
            $sHKLMx86 = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
            $sHKLM64 = "HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
        EndIf
    EndIf

    If BitAND($iArch, 1) Then
        Redim $aKeys[ UBound($aKeys) + 1]
        $aKeys [ UBound($aKeys) - 1] = $sHKLMx86
    EndIf

    If BitAND($iArch, 2) Then
        Redim $aKeys[ UBound($aKeys) + 1]
        $aKeys [ UBound($aKeys) - 1] = $sHKLM64
    EndIf


    For $i = 0 To UBound($aKeys) - 1
        $n = 1
        While 1
            $iFound = 1
            $aSubKey = _RegEnumKeyEx($aKeys[$i], $n)
            If @error Then ExitLoop

            $sSubKey = $aSubKey[0]
            $sKeyDate = StringRegExpReplace($aSubKey[1], "^(\d{4})/(\d{2})/(\d{2}).+", "$1$2$3")
            $sDisplayName = RegRead($aKeys[$i] & "\" & $sSubKey, "DisplayName")
            $sDate = RegRead($aKeys[$i] & "\" & $sSubKey, "InstallDate")
            If $sDate = "" Then $sDate = $sKeyDate

            If $sDisplayName <> "" Then
                 If $sValueName <> "" Then
                    $iFound = 0
                    $sValue = RegRead( $aKeys[$i] & "\" & $sSubKey, $sValueName)
                    If ( $iSearchMode = 0 AND StringInStr($sValue, $sFilter) = 1 ) OR _
                       ( $iSearchMode = 1 AND StringInStr($sValue, $sFilter) ) OR _
                       ( $iSearchMode = 2 AND $sValue = $sFilter ) OR _
                       ( $iSearchMode = 3 AND StringRegExp($sValue, $sFilter) ) Then
                            $iFound = 1
                    EndIf
                EndIf

                If $iFound Then
                    Redim $aResult[ UBound($aResult) + 1][ 4 + $aCols[0] ]
                    $aResult[ UBound($aResult) - 1][0] = $aKeys[$i]
                    $aResult[ UBound($aResult) - 1][1] = $sSubKey
                    $aResult[ UBound($aResult) - 1][2] = $sDisplayName
                    $aResult[ UBound($aResult) - 1][3] = $sDate

                    For $iCol = 1 To $aCols[0]
                        $aResult[ UBound($aResult) - 1][3 + $iCol] = RegRead( $aKeys[$i] & "\" & $sSubKey, $aCols[$iCol])
                    Next
                EndIf
            EndIf

            $n += 1
        WEnd
    Next

    $aResult[0][0] = UBound($aResult) - 1
    Return $aResult
EndFunc




; #FUNCTION# ====================================================================================================================
; Name ..........: _RegEnumKeyEx
; Description ...: Enumerates the subkeys of the specified open registry key. The function retrieves information about one subkey
;                  each time it is called.
; Syntax ........: _RegEnumKeyEx($sKey, $iInstance)
; Parameters ....: $sKey                - The registry key to read.
;                  $iInstance           - The 1-based key instance to retrieve.
; Return values .: Success              - A 1D array :
;                                          $aArray[0] = subkey name
;                                          $aArray[1] = time at which the enumerated subkey was last written
;                  Failure               - Returns 0 and set @eror to non-zero value
; Author ........: jguinch
; ===============================================================================================================================
Func _RegEnumKeyEx($sKey, $iInstance)
    If NOT IsDeclared("KEY_WOW64_32KEY") Then Local Const $KEY_WOW64_32KEY = 0x0200
    If NOT IsDeclared("KEY_WOW64_64KEY") Then Local Const $KEY_WOW64_64KEY = 0x0100
    If NOT IsDeclared("KEY_ENUMERATE_SUB_KEYS") Then Local Const $KEY_ENUMERATE_SUB_KEYS = 0x0008

    If NOT IsDeclared("tagFILETIME") Then Local Const $tagFILETIME = "struct;dword Lo;dword Hi;endstruct"

    Local $iSamDesired = $KEY_ENUMERATE_SUB_KEYS

    Local $iX64Key = 0, $sRootKey, $aResult[2]

    Local $sRoot = StringRegExpReplace($sKey, "\\.+", "")
    Local $sSubkey = StringRegExpReplace($sKey, "^[^\\]+\\", "")

    $sRoot = StringReplace($sRoot, "64", "")
    If @extended Then $iX64Key = 1

    If NOT IsInt($iInstance) OR $iInstance < 1 Then Return SetError(2, 0, 0)

    Switch $sRoot
        Case "HKCR", "HKEY_CLASSES_ROOT"
            $sRootKey = 0x80000000
        Case "HKLM", "HKEY_LOCAL_MACHINE"
            $sRootKey = 0x80000002
        Case "HKCU", "HKEY_CURRENT_USER"
            $sRootKey = 0x80000001
        Case "HKU", "HKEY_USERS"
            $sRootKey = 0x80000003
        Case  "HKCC", "HKEY_CURRENT_CONFIG"
            $sRootKey = 0x80000005
        Case Else
            Return SetError(1, 0, 0)
    EndSwitch

    If StringRegExp(@OSArch, "64$") Then
        If @AutoItX64 OR $iX64Key Then
            $iSamDesired = BitOR($iSamDesired, $KEY_WOW64_64KEY)
        Else
            $iSamDesired = BitOR($iSamDesired, $KEY_WOW64_32KEY)
        EndIf
    EndIf

    Local $aRetOPen = DllCall('advapi32.dll', 'long', 'RegOpenKeyExW', 'handle', $sRootKey, 'wstr', $sSubKey, 'dword', 0, 'dword', $iSamDesired, 'ulong_ptr*', 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aRetOPen[0] Then Return SetError(10, $aRetOPen[0], 0)

    Local $hKey = $aRetOPen[5]

    Local $tFILETIME = DllStructCreate($tagFILETIME)
    Local $lpftLastWriteTime = DllStructGetPtr($tFILETIME)

    Local $aRetEnum = DllCall('Advapi32.dll', 'long', 'RegEnumKeyExW', 'long', $hKey, 'dword', $iInstance - 1, 'wstr', "", 'dword*', 255, 'dword', "", 'ptr', "", 'dword', "", 'ptr', $lpftLastWriteTime)
    If Not IsArray($aRetEnum) OR $aRetEnum[0] <> 0 Then Return SetError( 3, 0, 1)

    Local $tFILETIME2 = _Date_Time_FileTimeToLocalFileTime($lpftLastWriteTime)
    Local $localtime = _Date_Time_FileTimeToStr($tFILETIME2, 1)

    $aResult[0] = $aRetEnum[3]
    $aResult[1] = $localtime

    Return $aResult
EndFunc
Edited by jguinch

Share this post


Link to post
Share on other sites



Very nice work

Is there a way to search for all keys but add displayname in colum2 so there is a reference to what keys like this relate to ?

{01D249F7-CED7-9302-BD00-5D6D15E9AB42}

Share this post


Link to post
Share on other sites

Thanks Chimaera. You're right.

Well, I cannot explain why, but I forgot to add DisplayName an UninstallString values in the returned array... :ermm:

It's done now : DisplayName in col2 and UninstallString in col3.

Share this post


Link to post
Share on other sites

Sometimes I find that some packages are listed here with uninstall keys:

HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionInstallerUserDataS-1-5-18Products

Share this post


Link to post
Share on other sites

Very nice work, as per usual.  I have been using this for the past few months and have not had an issue:

Is there a limitation of ripdads implementation you overcame, or other benefits your solution provides?  Most of your stuff has been ridiculously well thought out, and I tend to overlook the obvious...


,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

boththose, I didn't see this (nice) code before now... o:)

The first difference with mine, is the InstallDate : my code returns the installation date (as showed in the control panel) even if the InstallDate is not set in the registry. (this job was not easy with RegEnumKeyEx)

Also, my function allows simple or advanced filters (like wintitles), and a possibility to search for x86 or/and x64 keys.

Perhaps I should change the name of the function, call it _UninstallSearch or something like this.

Edit : thanks to JFX for the registry date idea !

Edited by jguinch

Share this post


Link to post
Share on other sites

Thx for the update i was wondering though is it possible to change the order they appear on the array window to

Display Name, Date, Key, Subkey ? As this seems to me a more sensible approach as you would probably look for the name first

I changed this around RegistryPath|RegistrySubKey|DisplayName|Date

But it just changed the headers.

On a side note im currently using a script by DXR4WE which gives 182 uninstallers on my machine

Yet yours gives 125?

Im guessing the difference is the other one uses extra keys like these

Global $aRegPath = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall\|' & _
        'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\|' & _
        'HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\|' & _
        'HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\|' & _
        'HKCU64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\'
$aRegPath = StringSplit($aRegPath, "|")

Complete script for reference

#RequireAdmin
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Version=Beta
#AutoIt3Wrapper_Icon=compile\chimaera_red.ico
#AutoIt3Wrapper_Outfile=Registry Uninstall Search.exe
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <_RegEnumKeyValEx.au3>
#include <Array.au3>

Global Const $sPatternGUID = "\{?(.)(.)(.)(.)(.)(.)(.)(.)-?(.)(.)(.)(.)-?(.)(.)(.)(.)-?(.)(.)(.)(.)-?(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)\}?"
Global Const $sComponentIdPattern  = "$8$7$6$5$4$3$2$1$12$11$10$9$16$15$14$13$18$17$20$19$22$21$24$23$26$25$28$27$30$29$32$31"
;;Global Const $scGUIDPattern = "(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)"
Global Const $sGUIDPattern  = "{$8$7$6$5$4$3$2$1-$12$11$10$9-$16$15$14$13-$18$17$20$19-$22$21$24$23$26$25$28$27$30$29$32$31}"

; #FUNCTION# =======================================================================================================================================================
; Name...........: _GetCompressedGUID
; Description ...: Connvert String GUID to String Compressed GUID
; Syntax.........: _GetCompressedGUID($sGUID[, $iFlags])
; Parameters ....: $sGUID - String GUID
;                  $iFlags - Optional, (Default = 0), if $iFlags $sGUID must be contain String Compressed GUID
; Return values .: String Product Properties, and set error
; Author ........: DXRW4E
; Modified.......:
; Remarks .......:
; Link ..........:
; Example .......:
; Note ..........:
; ==================================================================================================================================================================
Func _GetCompressedGUID($sGUID, $iFlags = 0)
    Return StringRegExpReplace($sGUID, $sPatternGUID, ($iFlags ? $sGUIDPattern : $sComponentIdPattern))
EndFunc


Global $aUninstallCheck, $aKeyList[1] = [0], $aMsiPath, $sMsiPath = "HKLM\SOFTWARE\Classes\Installer\Products\"
Global $aRegPath = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall\|' & _
        'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\|' & _
        'HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\|' & _
        'HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\|' & _
        'HKCU64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\'
$aRegPath = StringSplit($aRegPath, "|")

For $i = 1 To $aRegPath[0]
    $aRegEnumKeyEx = _RegEnumKeyEx($aRegPath[$i], 256, "*","*") ;*UninstallS*
    If Not @Error Then
        ReDim $aKeyList[$aKeyList[0] + $aRegEnumKeyEx[0] + 1]
        For $y = 1 To $aRegEnumKeyEx[0]
            $aKeyList[$y + $aKeyList[0]] = $aRegEnumKeyEx[$y]
        Next
        $aKeyList[0] += $aRegEnumKeyEx[0]
    EndIf
Next
If $aKeyList[0] Then
    $aUninstallCheck = _RegEnumValEx($aKeyList, 256, "*UninstallS*")
    If Not @Error Then
        For $i = 1 To $aUninstallCheck[0][0]
            $aMsiPath = StringRegExp($aUninstallCheck[$i][3], "^(?i)\h*MsiExec.exe\h+/\w\h*(\{[^\}]+\})", 1)
            If @Error then ContinueLoop
            ; Example
            ;; Example $DotNet4 = "HKLM\SOFTWARE\Classes\Installer\Products\%NetFX_Client_InstallerCode%"
            ;;RegRead($DotNet4, "AdvertiseFlags") - > %REG_DWORD%,"388"
            ;;RegRead($DotNet4, "Assignment") - > %REG_DWORD%,"1"
            ;;RegRead($DotNet4, "AuthorizedLUAApp") - > %REG_DWORD%,"0"
            ;;RegRead($DotNet4, "Clients") - > %REG_MULTI_SZ%,":"
            ;;RegRead($DotNet4, "InstanceType") - > %REG_DWORD%,"0"
            ;;RegRead($DotNet4, "Language") - > %REG_DWORD%,"0"
            ;;RegRead($DotNet4, "PackageCode") - > %REG_SZ%,"%NetFX_Client_PackageCode%"
            ;;RegRead($DotNet4, "ProductName", ,"%CoreProductName%"
            ;;RegRead($DotNet4, "Version") - > %REG_DWORD%,"67139183"
            ;;RegRead($DotNet4 & "\SourceList", "LastUsedSource") - > %REG_EXPAND_SZ%,"n;1;%SystemRoot%\Windows\Installer\"
            ;;RegRead($DotNet4 & "\SourceList", "PackageName") - > "netfx_Core_x86.msi"
            ;;RegRead($DotNet4 & "\SourceList\Media" ,"1") -> REG_SZ%";1"
            ;;RegRead($DotNet4 & "\SourceList\Net" ,"1") - > %REG_EXPAND_SZ%,"%SystemRoot%\Windows\Installer\"
            ;
            $aUninstallCheck[$i][3] &= @LF & RegRead($sMsiPath & _GetCompressedGUID($aMsiPath[0]) & "\SourceList", "PackageName")
            $aUninstallCheck[$i][3] &= @LF & StringRegExpReplace(RegRead($sMsiPath & _GetCompressedGUID($aMsiPath[0]) & "\SourceList", "LastUsedSource"), "^.*;(?=\w)", "")
        Next
    EndIf
EndIf
_ArrayDisplay($aUninstallCheck)

It may be nothing but i thought i would mention

Share this post


Link to post
Share on other sites

Chimaera, in DXR4WE's code, you can see this line :

Global $aRegPath = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall\|' & _
        'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\|' & _
        'HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\|' & _
        'HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\|' & _
        'HKCU64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\'

HKLMSoftware and HKLMSOFTWAREWow6432Node are the same keys with a x86 script running on a x64 operating system. Just one of these keys should be written in the $aRegPath variable, depending on the OS/Script architecture.

For this first reason, the result is not the same. Try to remove the line 'HKLMSOFTWAREWow6432NodeMicrosoftWindowsCurrentVersionUninstall|' & _

Also, I don't believe HKCU is a redirected key, so you can remove 'HKCU64SOFTWAREMicrosoftWindowsCurrentVersionUninstall' to

Now, can you explain what you are tring to do, I could help

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

That piece was actually me he added the being able to decipher the GUID codes

More like this you mean?

If @OSArch = "X64" Then
    $sRegPath = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall\|' & _
            'HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\|' & _
            'HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\'
ElseIf @OSArch = "X86" Then
    $sRegPath = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall\|' & _
            'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\|' & _
            'HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\'
EndIf

Btw i checked this at work and there is a fair bit of uninstallers in there as per comment higher up in the thread

HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionInstallerUserDataS-1-5-18Products

 

Edited by Chimaera

Share this post


Link to post
Share on other sites

The key you quote above is a dedicated key for software updates.My function is intended only to list the installed programs, not updates (at least for now).

I have read jazzyjeff's post, and did not answer him (sorry). Yes, the UserData key also contains a list  of folders for each user (from its account SID) : this key is not really easy to understand for me, and my first idea was oriented to uninstall apps that you can see in the Control Panel.

One day, if i can find enough time, I could make another fonction for this, bit not now...

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

Im closer now to the others now ive made some changes

Question if i may.

Is it possible to for uninstall strings and quiet uninstall strings at the same time? as i use both or do i need to run it twice?

Many thanks

Edited by Chimaera

Share this post


Link to post
Share on other sites

Well, just put in the 3rd parameter the list of values you want to retrieve :

$aList = _UninstallList("", "", "UninstallString|QuietUninstallString")

What do you want to list exatly ? (which product(s) ?)

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

Im listing all products so i can track down toolbars etc

tried this but now doesnt display the array

$aList = $aList = _UninstallList("", "", "UninstallString|QuietUninstallString")
_ArrayDisplay($aList, "All uninstall keys", Default, Default, Default, "DisplayName|Date|RegistryPath|RegistrySubKey")

Got this to work

$aList = _UninstallList("UninstallString", ".+", "UninstallString|QuietUninstallString", 3, 3)
_ArrayDisplay($aList, "UninstallString", Default, Default, Default, "DisplayName|Date|RegistryPath|RegistrySubKey|UninstallString|QuietUninstallString")
Edited by Chimaera

Share this post


Link to post
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
Sign in to follow this  
Followers 0

  • Similar Content

    • 31290
      By 31290
      Hello everyone, 
      I'm working on a WMIC uninstaller. A quite simple one with a button to display product names in a editable list (for copy/paste purposes) but the main problem is that in order to achieve this, in my corporation, normal users cannot uninstall softs.
      What I found/adapt so far:
      #include <ButtonConstants.au3> #include <ComboConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> $Form1 = GUICreate("wmic uninstaller", 300, 152, 337, 380) $Label1 = GUICtrlCreateLabel("Computername", 0, 8, 75, 17) $Input1 = GUICtrlCreateInput(@ComputerName, 0, 32, 125, 21) $Label2 = GUICtrlCreateLabel("wmic command", 150, 8, 77, 17) $Combo1 = GUICtrlCreateCombo("Model_Computer", 150, 32, 125, 25, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL)) GUICtrlSetData(-1, "Current_user|Installed_Apps|Serial_Number|Bios_Version") $Button1 = GUICtrlCreateButton("List Apps", 150, 72, 91, 49) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit case $button1 $wmi = GUICtrlRead($combo1) $pc = GUICtrlRead($input1) call($wmi,$pc) EndSwitch WEnd Func Model_Computer($pc) RunWait(@ComSpec & ' /c ' & 'wmic /node:' & $pc &' product get name > %temp%\apps.txt' ,"", @SW_HIDE) $file=(@TempDir & "/apps.txt") $fileread= FileRead($file) MsgBox(0, $pc , $fileread) FileDelete(@TempDir & "/apps.txt") EndFunc Here's the textual version I gave to my techs:
      Create cmd shortcut on Desktop, run it as a different user (using their own admin accounts). Once opened, type wmic Once wmic loaded, type product get name Wait for the list of installed soft to display Type product where name="Exact App name" call uninstall Type "Y" to confirm Wait for task execution Don't care about exit code App is uninstalled (verified by getting the list again)! In fact, I'd like to automatize this process.
      Any ideas over here?
      Thanks ^^