jguinch Posted August 15, 2014 Share Posted August 15, 2014 (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 !) expandcollapse popup#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 December 1, 2014 by jguinch Musashi 1 Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF Link to comment Share on other sites More sharing options...
Chimaera Posted August 16, 2014 Share Posted August 16, 2014 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} If Ive just helped you ... miracles do happen. Chimaera CopyRobo() * Hidden Admin Account Enabler * Software Location From Registry * Find Display Resolution * _ChangeServices() Link to comment Share on other sites More sharing options...
jguinch Posted August 16, 2014 Author Share Posted August 16, 2014 Thanks Chimaera. You're right. Well, I cannot explain why, but I forgot to add DisplayName an UninstallString values in the returned array... It's done now : DisplayName in col2 and UninstallString in col3. Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF Link to comment Share on other sites More sharing options...
jazzyjeff Posted August 18, 2014 Share Posted August 18, 2014 Sometimes I find that some packages are listed here with uninstall keys: HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionInstallerUserDataS-1-5-18Products Link to comment Share on other sites More sharing options...
jguinch Posted December 1, 2014 Author Share Posted December 1, 2014 (edited) New function version : adding the InstallDate value (even if not set in the registry) Edited December 1, 2014 by jguinch Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF Link to comment Share on other sites More sharing options...
iamtheky Posted December 1, 2014 Share Posted December 1, 2014 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... ,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-. |(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/ (_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_) | | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) ( | | | | |)| | \ / | | | | | |)| | `--. | |) \ | | `-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_| '-' '-' (__) (__) (_) (__) Link to comment Share on other sites More sharing options...
jguinch Posted December 1, 2014 Author Share Posted December 1, 2014 (edited) boththose, I didn't see this (nice) code before now... 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 December 1, 2014 by jguinch Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF Link to comment Share on other sites More sharing options...
Chimaera Posted December 2, 2014 Share Posted December 2, 2014 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 expandcollapse popup#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 If Ive just helped you ... miracles do happen. Chimaera CopyRobo() * Hidden Admin Account Enabler * Software Location From Registry * Find Display Resolution * _ChangeServices() Link to comment Share on other sites More sharing options...
jguinch Posted December 4, 2014 Author Share Posted December 4, 2014 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 Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF Link to comment Share on other sites More sharing options...
Chimaera Posted December 5, 2014 Share Posted December 5, 2014 (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 December 5, 2014 by Chimaera If Ive just helped you ... miracles do happen. Chimaera CopyRobo() * Hidden Admin Account Enabler * Software Location From Registry * Find Display Resolution * _ChangeServices() Link to comment Share on other sites More sharing options...
jguinch Posted December 5, 2014 Author Share Posted December 5, 2014 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... Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF Link to comment Share on other sites More sharing options...
Chimaera Posted December 8, 2014 Share Posted December 8, 2014 (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 December 8, 2014 by Chimaera If Ive just helped you ... miracles do happen. Chimaera CopyRobo() * Hidden Admin Account Enabler * Software Location From Registry * Find Display Resolution * _ChangeServices() Link to comment Share on other sites More sharing options...
jguinch Posted December 8, 2014 Author Share Posted December 8, 2014 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) ?) Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF Link to comment Share on other sites More sharing options...
Chimaera Posted December 8, 2014 Share Posted December 8, 2014 (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 December 8, 2014 by Chimaera If Ive just helped you ... miracles do happen. Chimaera CopyRobo() * Hidden Admin Account Enabler * Software Location From Registry * Find Display Resolution * _ChangeServices() Link to comment Share on other sites More sharing options...
jkdfh Posted April 19, 2020 Share Posted April 19, 2020 Hi, I have a problem with the date when the tool "DVDFab (x64) 11.0.7.4 (18/02/2020)" is installed: RegistrySubKey:DVDFab 11(x64) DisplayName:DVDFab (x64) 11.0.7.4 (18/02/2020) Date:18/02/2020 Greetings Link to comment Share on other sites More sharing options...
Musashi Posted April 19, 2020 Share Posted April 19, 2020 Thanks @jguinch for this helpful script (it is never too late to say this !). I know it is already "older", but for me it is new, because I haven't seen it until now . Finally it was the post from @jkdfh that brought it to my attention. "In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move." Link to comment Share on other sites More sharing options...
jkdfh Posted April 22, 2020 Share Posted April 22, 2020 There I join @Musashi, thanks @jguinch for the beautiful script. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now