teadrinker's script to get list of installed software

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
JoeWinograd
Posts: 2198
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

teadrinker's script to get list of installed software

29 Aug 2019, 16:44

Hi teadrinker (and anyone else who wants to jump in),

First, thanks for your terrific script posted in this thread:

https://www.autohotkey.com/boards/viewtopic.php?t=39668

It works well, but the output is missing some items. I ran it on a W7/64-bit system where Control Panel>Programs and Features shows 261 installed programs and 362 installed updates, for a total of 623. But the script shows only 357 (not counting the 11 "For more information..." and 11 "If you later install..." items shown below), so there are 266 missing.

The script shows all 261 installed programs, so all of the missing entries are installed updates. My main purpose in running this script is to look for installed browsers and the problem is that Internet Explorer 11 (which appears in Control Panel>Programs and Features>View installed updates) is one of the missing items. Any ideas on how to change the script to get the missing items?

I don't know if it is part of the problem and/or if it helps in troubleshooting, but, as mentioned above, there are these 22 items in the script's output:

Code: Select all

For more information, visit http://support.microsoft.com/kb/4087364., ,
For more information, visit http://support.microsoft.com/kb/4338420., ,
For more information, visit http://support.microsoft.com/kb/4344146., ,
For more information, visit http://support.microsoft.com/kb/4457016., ,
For more information, visit http://support.microsoft.com/kb/4457035., ,
For more information, visit http://support.microsoft.com/kb/4459942., ,
For more information, visit http://support.microsoft.com/kb/4470640., ,
For more information, visit http://support.microsoft.com/kb/4480055., ,
For more information, visit http://support.microsoft.com/kb/4483451., ,
For more information, visit http://support.microsoft.com/kb/4495588., ,
For more information, visit http://support.microsoft.com/kb/4506997., ,
If you later install a more recent service pack, this update will be uninstalled automatically.
If you later install a more recent service pack, this update will be uninstalled automatically.
If you later install a more recent service pack, this update will be uninstalled automatically.
If you later install a more recent service pack, this update will be uninstalled automatically.
If you later install a more recent service pack, this update will be uninstalled automatically.
If you later install a more recent service pack, this update will be uninstalled automatically.
If you later install a more recent service pack, this update will be uninstalled automatically.
If you later install a more recent service pack, this update will be uninstalled automatically.
If you later install a more recent service pack, this update will be uninstalled automatically.
If you later install a more recent service pack, this update will be uninstalled automatically.
If you later install a more recent service pack, this update will be uninstalled automatically.
Here's the script I'm running:

Code: Select all

; teadrinker original script except for FileAppend instead of MsgBox
; https://www.autohotkey.com/boards/viewtopic.php?t=39668
#NoEnv
SetBatchLines, -1
headers := [ "DISPLAYNAME", "VERSION", "PUBLISHER", "PRODUCTID"
           , "REGISTEREDOWNER", "REGISTEREDCOMPANY", "LANGUAGE", "SUPPORTURL"
           , "SUPPORTTELEPHONE", "HELPLINK", "INSTALLLOCATION", "INSTALLSOURCE"
           , "INSTALLDATE", "CONTACT", "COMMENTS", "IMAGE", "UPDATEINFOURL" ]
data := []
for k, v in headers
   data.Push( GetAppsInfo({ mask: v, offset: A_PtrSize*(k - 1) }) )

arr := []
for k, v in data
   for i, j in v
      arr[i, k] := j

for k, v in arr  {
   str .= (k = 1 ? "" : "`r`n")
   for i, j in v
      str .= (i = 1 ? "" : ", ") . j
}
;MsgBox, % str

; JW
Output:="c:\temp\InstalledSoftware.txt"
FileDelete,%Output%
FileAppend,%str%,%Output%
Run,%Output%
ExitApp

GetAppsInfo(infoType)  {
   static CLSID_EnumInstalledApps := "{0B124F8F-91F0-11D1-B8B5-006008059382}"
        , IID_IEnumInstalledApps  := "{1BC752E1-9046-11D1-B8B3-006008059382}"

        , AIM_DISPLAYNAME       := 0x00000001
        , AIM_VERSION           := 0x00000002
        , AIM_PUBLISHER         := 0x00000004
        , AIM_PRODUCTID         := 0x00000008
        , AIM_REGISTEREDOWNER   := 0x00000010
        , AIM_REGISTEREDCOMPANY := 0x00000020
        , AIM_LANGUAGE          := 0x00000040
        , AIM_SUPPORTURL        := 0x00000080
        , AIM_SUPPORTTELEPHONE  := 0x00000100
        , AIM_HELPLINK          := 0x00000200
        , AIM_INSTALLLOCATION   := 0x00000400
        , AIM_INSTALLSOURCE     := 0x00000800
        , AIM_INSTALLDATE       := 0x00001000
        , AIM_CONTACT           := 0x00004000
        , AIM_COMMENTS          := 0x00008000
        , AIM_IMAGE             := 0x00020000
        , AIM_READMEURL         := 0x00040000
        , AIM_UPDATEINFOURL     := 0x00080000

   pEIA := ComObjCreate(CLSID_EnumInstalledApps, IID_IEnumInstalledApps)
   arr := []
   while DllCall(NumGet(NumGet(pEIA+0) + A_PtrSize*3), Ptr, pEIA, PtrP, pINA) = 0  {
      VarSetCapacity(APPINFODATA, size := 4*2 + A_PtrSize*18, 0)
      NumPut(size, APPINFODATA)
      mask := "AIM_" . infoType.mask
      NumPut(%mask%, APPINFODATA, 4)
      DllCall(NumGet(NumGet(pINA+0) + A_PtrSize*3), Ptr, pINA, Ptr, &APPINFODATA)
      ObjRelease(pINA)
      if !pData := NumGet(APPINFODATA, 8 + infoType.offset)  {
         arr.Push("")
         continue
      }
      arr.Push( StrGet(pData, "UTF-16") )
      DllCall("Ole32\CoTaskMemFree", Ptr, pData)  ; not sure, whether it's needed
   }
   Return arr
}
It is identical to teadrinker's original script, except that I changed the MsgBox output to a text file via FileAppend.

Thanks much, Joe
teadrinker
Posts: 4326
Joined: 29 Mar 2015, 09:41
Contact:

Re: teadrinker's script to get list of installed software

29 Aug 2019, 17:49

JoeWinograd wrote: Any ideas on how to change the script to get the missing items?
Try this one:

Code: Select all

#NoEnv
SetBatchLines, -1

arr := GetAppsInfo()
for k, v in arr[1]
   headers .= (headers = "" ? "" : "|") . v.name

Gui, +Resize
Gui, Margin, 0, 0
Gui, Add, ListView, Grid, % headers
listViewArr := []
for k, v in arr
   for i, j in v
      listViewArr[k, i] := j.value
   
for k, v in listViewArr
   LV_Add("", v*)

Loop % arr[1].length()
   LV_ModifyCol(A_Index, "AutoHdr")
LV_ModifyCol(1, "Sort")
Gui, Show, w1200 h600, % "Found " . arr.MaxIndex() . " applications"
Return

GuiSize:
   GuiControl, Move, SysListView321, w%A_GuiWidth% h%A_GuiHeight%
   Return
   
GuiClose:
   ExitApp

GetAppsInfo() {
   static subKey    := "\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
        , infoNames := [ "DisplayName"  , "DisplayVersion", "InstallLocation"
                       , "InstallDate"  , "DisplayIcon"   , "InstallSource"
                       , "Publisher"    , "HelpLink"      , "HelpTelephone"
                       , "Contact"      , "Comments"      , "Readme"
                       , "URLInfoAbout" , "URLUpdateInfo" ]
        
   arr := [], used := {}
   Loop % A_Is64bitOS + 1 {
      SetRegView, % 32 * A_Index
      for k, root in ["HKCU", "HKLM"] {
         Loop, Reg, % root . subKey, K
         {
            appInfo := [], enumValue := ""
            for k, name in infoNames {
               RegRead, value, % root . subKey . "\" . A_LoopRegName, % name
               if (name = "DisplayName" && value = "")
                  continue 2
               if name in DisplayName,DisplayVersion
                  enumValue .= value
               if (name = "DisplayVersion") {
                  if used.HasKey(enumValue)
                     continue 2
                  used[enumValue] := ""
               }
               appInfo.Push({name: name, value: value})
            }
            arr.Push(appInfo)
         }
      }
   }
   Return arr
}
JoeWinograd wrote: My main purpose in running this script is to look for installed browsers and the problem is that Internet Explorer 11 (which appears in Control Panel>Programs and Features>View installed updates) is one of the missing items
However, this code doesn't show IE for me too. To check if IE is installed you could read the key

Code: Select all

RegRead, val, HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\IEXPLORE.EXE
MsgBox, % val
Last edited by teadrinker on 29 Aug 2019, 18:13, edited 1 time in total.
User avatar
JoeWinograd
Posts: 2198
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: teadrinker's script to get list of installed software

29 Aug 2019, 18:43

Hi teadrinker,
Thanks for the fast reply...much appreciated! This one comes up with more entries...454. A couple examples of what the new one finds that the previous one doesn't are 10 entries for Windows Live and 9 entries for Windows Software Development Kit. However, it's still 169 short and, in particular, doesn't find Internet Explorer 11. Regards, Joe
User avatar
JoeWinograd
Posts: 2198
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: teadrinker's script to get list of installed software

29 Aug 2019, 19:19

Our messages crossed...didn't see your edit when I posted. Thanks for the idea of the RegRead code for IE. I could use that method instead of the script for finding other browsers, too, such as Brave, Chrome, Firefox, Opera, Vivaldi, etc. (and Edge on W10), assuming that I can determine all of their registry entries. :) Thanks, Joe

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: No registered users and 275 guests