Sign in to follow this  
Followers 0
big_daddy

Uninstall Apps -=Big_Daddy Style=-

105 posts in this topic

#1 ·  Posted (edited)

This was the first script I released, and my code showed it horribly. This is why I decided to update it with some cool new features and optimized code.

It enumerates all the keys from HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall and checks those for the string values DisplayIcon, DisplayName, UninstallString, and QuietUninstallString. It then creates a sorted list of programs that have the ability to be uninstalled. From there you can select one or more programs to uninstall. There is also a checkbox to enable silent uninstall for programs that support it. This is indicated by a green icon in the last column. It also has the ability to do remote uninstalls using beyondexec.exe from BeyondLogic.

Thanks to:

  • Danny35d - Code contributions in previous version
  • gafrost - For DragListViewItems.au3 Examples
  • randallc - For _ArrayDelete2D()
Posted Image

Uninstall Apps v1.0.2.0 (June 1, 2007)

UninstallApps.zip Previous versions 1235+ downloads

---

WARNING - This version is not finished!

Uninstall Apps v2.0.0.11 (Jan 15th, 2008)

UninstallApps.zip

---

Features

  • Scan local or remote computers
  • Press "ESC" to end processing
  • Silent uninstall indicators
  • Green = Entry for QuietUninstallString was found (should always work)
  • Yellow = MSI Package /I /qn /norestart will be attempted (may not work)
  • Gray = No silent uninstall available
  • Filtering (use minus to exclude)
  • MICROSOFT -OFFICE (Everything with Microsoft, but not Office)
  • MICROSOFT OFFICE (Everything with both Microsoft and Office)
  • Verbose log file
---

Update History

  • v1.0.0 - Complete Rewrite
  • v1.0.1
  • Now strips quotes from icon paths
  • Filter option (similar to google)
  • Added additional silent status icon
  • v1.0.2
  • Fixed registry values containing a pipe (Thanks jkuzo)
  • Fixed WIN98 issue was accessing registry incorrectly (Thanks Zedna)
Edited by big_daddy

Share this post


Link to post
Share on other sites



Well this is my first attempt at trying to provide a script that might be useful to a few people. Basicly it pulls all the keys from HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall and checks them for the string values DisplayName or #DisplayName. Then it creates a nice sorted list of the DisplayNames and Key Names. Later I'm hoping to be able to include the DisplayIcon, but haven't found a command line utility that will convert icons to images. BatchIconExtractor is a command line utility that will extract icons from .exe files. If anyone wants to help improve it feel free.

I haven't used this function, but check out GUICtrlSetImage. It can use the icon from within an EXE or DLL, although you might need to use GUICtrlCreateCheckbox for the items. Then you don't need to extract the icons!

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Wow I didn't know it could pull the icon from a file. I updated my first post with my attempt to use the GuiCtrlSetImage(). Can someone tell me where the 1 after the icon is coming from?

Edited by big_daddy

Share this post


Link to post
Share on other sites

...Then it creates a nice sorted list of the DisplayNames and Key Names....

Where is this list created?

Share this post


Link to post
Share on other sites

...Then it creates a nice sorted list of the DisplayNames and Key Names....

Where is this list created?

It is created in the Gui list view.

Share this post


Link to post
Share on other sites

Updated my first post again. Now it pulls the DisplayIcons, but it changes the icon on every listitem when it loops. Anyone know of a way around this?

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

I think you need to make your $image variable an array or else it's the same variable for All entries.

so maybe adding something like this

Dim $Image[ubound($TotalKeys)]
$Image[$i-1] = GUICtrlSetImage($ulist, $Icon[$i - 1], "", 0)

I haven't gotten it to work, but i think that making the image Var an Array would do the trick.

Edited by blademonkey

---"Educate the Mind, Make Savage the Body" -Mao Tse Tung

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

Try this:

Func ReadKeys()
    
    Dim $Key = "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall"
    Dim $TotalKeys = _RegKeyCount ($Key)
    Dim $List[$TotalKeys]
    Dim $Icon[$TotalKeys]
 ;Dim $Icon = "C:\Program Files\AutoIt3\AutoIt3.exe"
    
    For $i = 1 To $TotalKeys
        $var = RegEnumKey($Key, $i)
        If @error <> 0 Then ExitLoop
        $List[$i - 1] = RegRead($Key & "\" & $var, "DisplayName")
        If $List[$i - 1] = "" Then $List[$i - 1] = RegRead($Key & "\" & $var, "#DisplayName")
        If $List[$i - 1] = "" Then $List[$i - 1] = "No Display Name"
        $Icon[$i - 1] = RegRead($Key & "\" & $var, "DisplayIcon")
        If $Icon[$i - 1] = "" Then $Icon[$i - 1] = "No Icon"
        GUICtrlCreateListViewItem("" & "|" & $List[$i - 1] & "|" & $var, $ulist)
        GUICtrlSetImage(-1, $Icon[$i - 1], "", 0)
    Next
    
    $Count = _GUICtrlListCount ($ulist)
 ; _GUICtrlListViewSort ($ulist, $Count, 1)
EndFunc;==>ReadKeys

Func Stop()
    Exit
EndFunc;==>Stop
To make work the only thing the I chante was:

1) Move the GUICtrlSetImage() function after GUICtrlCreateListViewItem. The way you were using before only update the first GUICreateListViewItem no the last one that was created.

2) On the GUICreateListViewItem rename $Image for ""

3) Remark _GUICtrlListViewSort when the script run this line will refresh the listview and you loose the icons.

Edited by Danny35d

AutoIt Scripts:NetPrinter - Network Printer UtilityRobocopyGUI - GUI interface for M$ robocopy command line

Share this post


Link to post
Share on other sites

Once again I updated my first post. Thanks for all the help! Next thing I need help with is how to pull just the file path from the DisplayIcon value.

For example either:

C:\Program Files\AutoIt3\AutoIt3.exe,0

or

"C:\Program Files\AutoIt3\AutoIt3.exe"

Need to come out like:

C:\Program Files\AutoIt3\AutoIt3.exe

I'm guessing that StringSplit() would be used here?

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

for a little bit more icons :lmao:

Check for parameter ",0" in Registry !

Func ReadKeys()

Dim $Key = "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall"

Dim $TotalKeys = _RegKeyCount ($Key)

Dim $List[$TotalKeys]

Dim $Icon[$TotalKeys]

;Dim $Icon = "C:\Program Files\AutoIt3\AutoIt3.exe"

For $i = 1 To $TotalKeys

$var = RegEnumKey($Key, $i)

If @error <> 0 Then ExitLoop

$List[$i - 1] = RegRead($Key & "\" & $var, "DisplayName")

If $List[$i - 1] = "" Then $List[$i - 1] = RegRead($Key & "\" & $var, "#DisplayName")

If $List[$i - 1] = "" Then $List[$i - 1] = "No Display Name"

$Icon[$i-1]= RegRead($Key & "\" & $var, "DisplayIcon")

If StringRight($Icon[$i-1],1)="0" then $Icon[$i-1]= StringLeft($Icon[$i-1],StringLen($Icon[$i-1])-2);check parameter ,0 exist

If $Icon[$i - 1] = "" Then $Icon[$i - 1]=@SystemDir &"\progman.exe"

;maybe you look for the program exe file with key InstallLocation ???!!! to get the Icon

GUICtrlCreateListViewItem("" & "|" & $List[$i - 1] & "|" & $var, $ulist)

GUICtrlSetImage(-1, $Icon[$i - 1], "", 0)

Next

$Count = _GUICtrlListCount ($ulist)

;_GUICtrlListViewSort ($ulist, $Count,1) Disabled because Icons lost by this function

EndFunc;==>ReadKeys

Edited by Micha1405

Share this post


Link to post
Share on other sites

Script now pulls a few more icons. Check first post for update!

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

Once again I updated my first post. Thanks for all the help! Next thing I need help with is how to pull just the file path from the DisplayIcon value.

For example either:

C:\Program Files\AutoIt3\AutoIt3.exe,0

or

"C:\Program Files\AutoIt3\AutoIt3.exe"

Need to come out like:

C:\Program Files\AutoIt3\AutoIt3.exe

I'm guessing that StringSplit() would be used here?

Try this:

$Icon[$i - 1] = StringReplace(StringMid($Icon[$i - 1], 1, StringInStr($Icon[$i - 1], ',') - 1), '"', '')

1) StringInStr() find the positon of the coma minus 1

2) StringMid() take out the string starting at 1 to StringInStr() position

3) StringReplace() remove the quotes

Edited by Danny35d

AutoIt Scripts:NetPrinter - Network Printer UtilityRobocopyGUI - GUI interface for M$ robocopy command line

Share this post


Link to post
Share on other sites

Try this:

$Icon[$i - 1] = StringReplace(StringMid($Icon[$i - 1], 1, StringInStr($Icon[$i - 1], ',') - 1), '"', '')

1) StringInStr() find the positon of the coma minus 1

2) StringMid() take out the string starting at 1 to StringInStr() position

3) StringReplace() remove the quotes

Thanks for the improved code.

How could I sort the list before it creates the list items?

Share this post


Link to post
Share on other sites

Your welcome.....

How could I sort the list before it creates the list items?

Try this code:

Func ReadKeys()
    
    Dim $Key = "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall"
    Dim $TotalKeys = _RegKeyCount ($Key)
    Dim $List[$TotalKeys]
    Dim $Icon[$TotalKeys]
    
    For $i = 1 To $TotalKeys
        $var = RegEnumKey($Key, $i)
        If @error <> 0 Then ExitLoop
        $List[$i - 1] = RegRead($Key & "\" & $var, "DisplayName")
        If $List[$i - 1] = "" Then $List[$i - 1] = RegRead($Key & "\" & $var, "#DisplayName")
        If $List[$i - 1] = "" Then $List[$i - 1] = "No Display Name"
        $Icon[$i - 1] = RegRead($Key & "\" & $var, "DisplayIcon")
        $Icon[$i - 1] = StringReplace(StringMid($Icon[$i - 1], 1, StringInStr($Icon[$i - 1], ',') - 1), '"', '')
        If $Icon[$i - 1] = "" Then $Icon[$i - 1] = "SHELL32.DLL"
        $List[$i - 1] = $List[$i - 1] & '|' & $var & '|' & $Icon[$i - 1]        
    Next
    _ArraySort($List)
    For $i = 1 To UBound($List)
        $Item = StringSplit($List[$i - 1], '|')
        GUICtrlCreateListViewItem("" & "|" & $Item[1] & "|" & $Item[2], $ulist)
        GUICtrlSetImage(-1, $Item[3])
    Next
    
EndFunc;==>ReadKeys

AutoIt Scripts:NetPrinter - Network Printer UtilityRobocopyGUI - GUI interface for M$ robocopy command line

Share this post


Link to post
Share on other sites

Your code worked great, thanks a lot. Updated my first post with the new code. Now all I need to do to come up with an uninstall function.

Share this post


Link to post
Share on other sites

:lmao: my solution:

#include <RegCount.au3>

#include <Constants.au3>

#include <Array.au3>

#include <GUIConstants.au3>

#include <GuiList.au3>

#include <GuiListView.au3>

Dim $Key = "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall"

dim $Debug = 1

dim $SelectKey

HotKeySet("{Esc}", "Stop")

$mainWindows = GUICreate("Display Uninstall", 695, 400, -1, -1)

$ulist = GUICtrlCreateListView("Icon|Display Name|Key Name", 10, 40, 680, 350, -1, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES))

_GUICtrlListViewSetColumnWidth ($ulist, 0, 40)

_GUICtrlListViewSetColumnWidth ($ulist, 1, 310)

_GUICtrlListViewSetColumnWidth ($ulist, 2, 310)

$but1 = GUICtrlCreateButton("Read Registry", 10, 10)

$but2 =GUICtrlCreateButton("Uninstall select Program", 570, 10)

$var=GUICtrlSetState($but2,$GUI_DISABLE)

GUISetState(@SW_SHOW)

While 1; Start the gui

$MSG = GUIGetMsg()

Select

Case $MSG = $but1

_GUICtrlListViewDeleteAllItems ($ulist)

ReadKeys()

$var=GUICtrlSetState($but2,$GUI_ENABLE) ;List is load enable Button to do something

Case $MSG=$but2

ReadSelectItemfromUList()

UninstallProgram()

Case $MSG = $GUI_EVENT_CLOSE

Exit

EndSelect

WEnd

Func Stop() ;exit the gui

Exit

EndFunc;==>Stop

Func ReadKeys() ;read the keys from uninstall section

GUISetCursor(15,1)

Dim $TotalKeys = _RegKeyCount ($Key)

Dim $List[$TotalKeys]

Dim $Icon[$TotalKeys]

For $i = 1 To $TotalKeys

$var = RegEnumKey($Key, $i)

If @error <> 0 Then ExitLoop

$List[$i - 1] = RegRead($Key & "\" & $var, "DisplayName")

If $List[$i - 1] = "" Then $List[$i - 1] = RegRead($Key & "\" & $var, "#DisplayName")

If $List[$i - 1] = "" Then $List[$i - 1] = "No Display Name"

$Icon[$i - 1] = RegRead($Key & "\" & $var, "DisplayIcon")

$Icon[$i - 1] = StringReplace(StringMid($Icon[$i - 1], 1, StringInStr($Icon[$i - 1], ',') - 1), '"', '')

If $Icon[$i - 1] = "" Then $Icon[$i - 1] = "SHELL32.DLL"

$List[$i - 1] = $List[$i - 1] & '|' & $var & '|' & $Icon[$i - 1]

Next

_ArraySort($List)

For $i = 1 To UBound($List)

$Item = StringSplit($List[$i - 1], '|')

GUICtrlCreateListViewItem("" & "|" & $Item[1] & "|" & $Item[2], $ulist)

GUICtrlSetImage(-1, $Item[3])

Next

GUISetCursor(2,1)

EndFunc;==>ReadKeys

Func ReadSelectItemfromUList() ;Get the selected item from list

Dim $Iarray[_GUICtrlListViewGetItemCount ($ulist)]

$ret = _GUICtrlListViewGetItemText ($ulist)

;then read the uninstall key from Registry

$readkey=StringSplit($ret,"|")

$SelectKey = RegRead($key&"\"&$readKey[2],"UninstallString")

EndFunc

Func UninstallProgram(); do uninstall command

Run($SelectKey)

; I have found now way to get the really Uninstall Process because some are packed! Problem ???

$var=MsgBox(32,"Unistall","Ready for refresh the list")

_GUICtrlListViewDeleteAllItems ($ulist)

ReadKeys()

EndFunc

Share this post


Link to post
Share on other sites

:lmao: much better ! with waiting for uninstall is complete ;)

#include <RegCount.au3>

#include <Constants.au3>

#include <Array.au3>

#include <GUIConstants.au3>

#include <GuiList.au3>

#include <GuiListView.au3>

Dim $Key = "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall"

dim $Debug = 1

dim $SelectKey

Dim $readkey

HotKeySet("{Esc}", "Stop")

$mainWindows = GUICreate("Display Uninstall", 695, 400, -1, -1)

$ulist = GUICtrlCreateListView("Icon|Display Name|Key Name", 10, 40, 680, 350, -1, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES))

_GUICtrlListViewSetColumnWidth ($ulist, 0, 40)

_GUICtrlListViewSetColumnWidth ($ulist, 1, 310)

_GUICtrlListViewSetColumnWidth ($ulist, 2, 310)

$but1 = GUICtrlCreateButton("Read Registry", 10, 10)

$but2 =GUICtrlCreateButton("Uninstall select Program", 570, 10)

$var=GUICtrlSetState($but2,$GUI_DISABLE)

GUISetState(@SW_SHOW)

While 1; Start the gui

$MSG = GUIGetMsg()

Select

Case $MSG = $but1

_GUICtrlListViewDeleteAllItems ($ulist)

ReadKeys()

$var=GUICtrlSetState($but2,$GUI_ENABLE) ;List is load enable Button to do something

Case $MSG=$but2

ReadSelectItemfromUList()

UninstallProgram()

Case $MSG = $GUI_EVENT_CLOSE

Exit

EndSelect

WEnd

Func Stop() ;exit the gui

Exit

EndFunc;==>Stop

Func ReadKeys() ;read the keys from uninstall section

GUISetCursor(15,1)

Dim $TotalKeys = _RegKeyCount ($Key)

Dim $List[$TotalKeys]

Dim $Icon[$TotalKeys]

For $i = 1 To $TotalKeys

$var = RegEnumKey($Key, $i)

If @error <> 0 Then ExitLoop

$List[$i - 1] = RegRead($Key & "\" & $var, "DisplayName")

If $List[$i - 1] = "" Then $List[$i - 1] = RegRead($Key & "\" & $var, "#DisplayName")

If $List[$i - 1] = "" Then $List[$i - 1] = "No Display Name"

$Icon[$i - 1] = RegRead($Key & "\" & $var, "DisplayIcon")

$Icon[$i - 1] = StringReplace(StringMid($Icon[$i - 1], 1, StringInStr($Icon[$i - 1], ',') - 1), '"', '')

If $Icon[$i - 1] = "" Then $Icon[$i - 1] = "SHELL32.DLL"

$List[$i - 1] = $List[$i - 1] & '|' & $var & '|' & $Icon[$i - 1]

Next

_ArraySort($List)

For $i = 1 To UBound($List)

$Item = StringSplit($List[$i - 1], '|')

GUICtrlCreateListViewItem("" & "|" & $Item[1] & "|" & $Item[2], $ulist)

GUICtrlSetImage(-1, $Item[3])

Next

GUISetCursor(2,1)

EndFunc;==>ReadKeys

Func ReadSelectItemfromUList() ;Get the selected item from list

Dim $Iarray[_GUICtrlListViewGetItemCount ($ulist)]

$ret = _GUICtrlListViewGetItemText ($ulist)

;then read the uninstall key from Registry

$readkey=StringSplit($ret,"|")

$SelectKey = RegRead($key&"\"&$readKey[2],"UninstallString")

EndFunc

Func UninstallProgram(); do uninstall command

Run($SelectKey)

while 1;until Regkey not exist any longer

$var=RegRead($key&"\"&$readKey[2],"UninstallString")

If @error then ExitLoop

WEnd

_GUICtrlListViewDeleteAllItems ($ulist)

ReadKeys()

EndFunc

Share this post


Link to post
Share on other sites

#18 ·  Posted (edited)

Nice work, thanks for the help. I added a few things to it just in case the selected item doesn't have an uninstallstring. I also added automatic column resizing based on the width of the window. Last but not least I added docking for the buttons and listview so they wouldn't move around. Oh yeah, I updated the script in my first post.

Edited by big_daddy

Share this post


Link to post
Share on other sites

#19 ·  Posted (edited)

Nice work big_daddy and Micha1405, I did some changes hope you like it.....

1) Add StatusBar to the GUI.

2) Add grid lines to the listview and also set listview for multiselections.

3) Now you can uninstall multipler selections.

4) Add a progress bar if there is more than one application selected.

5) The script now use QuietUninstallString Regkey for silent uninstall, if key is missing then try UninstallString regkey.

6) Improve the way of refreshing listview after uninstall, no need to delete the entire list.

Note: Just for now I disable resizing. Need to figure out how to move the statusbar when GUI maximize.

Edit:

1) Rename button Read Registry to Refresh List.

2) Script load Uninstall information with a progress bar.

Edited by Danny35d

AutoIt Scripts:NetPrinter - Network Printer UtilityRobocopyGUI - GUI interface for M$ robocopy command line

Share this post


Link to post
Share on other sites

#20 ·  Posted (edited)

I really like the looks of the gridlines and statusbar. I had to make a change with the way it handled a missing uninstallstring because it was still trying to run the uninstall. I also changed the amount of time it waited between each list item and between the last item and the statusbar update. Great addition to the script, thanks a lot. Updated my first post.

Edited by big_daddy

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