bigirishape Posted March 6, 2013 Share Posted March 6, 2013 This question is a bit of a follow-up from this post: I used the code provided by boththose (and credits to ripdad) to try and mold the script into doing what I am trying to achieve, but I've run into a snag of sorts, and I haven't been able to puzzle it out.Before I start, let me say I haven't coded much of anything since 2004/2005...so to say I'm rusty...that would be very polite...I'm trying to inventory the list of installed programs, print out a subset of programs applicable to the software I'm trying to find, and then provide a single-button-click to install any software that needs to be updated. The program works, all of the relevant messages are displayed and it seems like it displays the proper software in the list and runs the proper .exe at the right time. Everything looks good...On my test PC, I ran the script .exe, did a right-click Uninstall on the Java software. Seems to have run fine. Executing the script again shows no listing of Java. I run the Java installer from the button at the bottom (64-bit) and the installer runs fine. I see Java installed in the Control Panel. I actually see the Java key in the Uninstall registry keys. However, the script no longer lists Java as an installed program.Any insight would be appreciated...I've been staring at boththose and ripdad's code for a while, but I can't find the issue...expandcollapse popup#include Opt("TrayAutoPause", 0) Opt('GUIOnEventMode', 1) Opt('GUICloseOnEsc' , 1) Global $i ;Filling an array with software names I want to check against the installed software listing array. Global $m[2] = ["java", "openvpn"] Global $n Local $sSft Global $sGui = GUICreate('Currently Installed Software for ' & @OSVersion & ' ' & @OSArch, 810, 650, -1, -1) Global $sLvw = GUICtrlCreateListView('#|Installed Software|Display Version|Publisher|Uninstall String', 5, 5, 800, 600) ;Function call to create a C:\temp folder and copy the .exe's to it for the software to be updated. _FileList() _ComputerGetSoftware($sSft) For $i = 1 To ubound($sSft) - 1 GUICtrlCreateListViewItem($i & '|' & $sSft[$i][0] & '|' & $sSft[$i][1] & '|' & $sSft[$i][2] & '|' & $sSft[$i][3], $sLvw) Next GUICtrlSendMsg($sLvw, 0x101E, 1, 175) GUICtrlSendMsg($sLvw, 0x101E, 2, 65) GUICtrlSendMsg($sLvw, 0x101E, 3, 150) GUICtrlSendMsg($sLvw, 0x101E, 4, 350) Local $mMen = GUICtrlCreateContextMenu($sLvw) Local $CopI = GUICtrlCreateMenuItem('Uninstall Current Selection', $mMen) GUICtrlSetOnEvent($CopI, '_Uninstall') ;Creating buttons on the GUI to call the .exe's to install software from C:\temp. Local $java32 = GUICtrlCreateButton(' Java Update (32bit) ', 5, 615 ) GUICtrlSetOnEvent($java32, '_JavaUpdate32') Local $java64 = GUICtrlCreateButton(' Java Update (64bit) ',175, 615) GUICtrlSetOnEvent($java64, '_JavaUpdate64') Local $VPN = GUICtrlCreateButton(' OpenVPN 2.2 ',550, 615) GUICtrlSetOnEvent($VPN, '_OpenVPN') ;Function call to check Windows Registry for Windows Updates enabled or not. _WUpdateRegRead() GUISetOnEvent(-3, '_AllExit') GUISetState(@SW_SHOW, $sGui) While 1 Sleep(10) WEnd ; Func _AllExit() GUIDelete($sGui) Exit EndFunc ; Func _Uninstall() Local $proc = StringSplit(GUICtrlRead(GUICtrlRead($sLvw)), '|', 1) If $proc[1] == 0 Then Return -1 If $proc[5] Then RunWait ($proc[5]) exit EndFunc ; Func _ComputerGetSoftware(ByRef $aSoftwareInfo) Local Const $UnInstKey = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" Local $i = 1 Local $n = 0 Dim $aSoftwareInfo[1][4] $input = inputbox ("Which Software" , "You are running " & @OSVersion & " " & @OSARCH & @CRLF & @CRLF & "Which Software would you like to view, ALL or Some?", 'Some') If @Error = 1 Then Exit If $input = 'ALL' Then For $j = 1 To 500 $AppKey = RegEnumKey($UnInstKey, $j) If @error <> 0 Then Exitloop If RegRead($UnInstKey & "\" & $AppKey, "DisplayName") = '' Then ContinueLoop ReDim $aSoftwareInfo[UBound($aSoftwareInfo) + 1][4] $aSoftwareInfo[$i][0] = StringStripWS(StringReplace(RegRead($UnInstKey & "\" & $AppKey, "DisplayName"), " (remove only)", ""), 3) $aSoftwareInfo[$i][1] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "DisplayVersion"), 3) $aSoftwareInfo[$i][2] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "Publisher"), 3) $aSoftwareInfo[$i][3] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "UninstallString"), 3) $i = $i + 1 Next $aSoftwareInfo[0][0] = UBound($aSoftwareInfo, 1) - 1 If $aSoftwareInfo[0][0] < 1 Then SetError(1, 1, 0) Return _ArraySort($aSoftwareInfo,0,1) Else IF $input = 'Some' Then ;Looping the array from above, checking for "java" or "openvpn" in the list of installed programs. For $n = 0 to 2 - 1 For $j = 1 To 500 $AppKey = RegEnumKey($UnInstKey, $j) If @error <> 0 Then Exitloop $Reg = RegRead($UnInstKey & "\" & $AppKey, "DisplayName") $string = stringinstr($Reg, $m[$n]) If $string = 0 Then Continueloop ReDim $aSoftwareInfo[UBound($aSoftwareInfo) + 1][4] $aSoftwareInfo[$i][0] = StringStripWS(StringReplace(RegRead($UnInstKey & "\" & $AppKey, "DisplayName"), " (remove only)", ""), 3) $aSoftwareInfo[$i][1] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "DisplayVersion"), 3) $aSoftwareInfo[$i][2] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "Publisher"), 3) $aSoftwareInfo[$i][3] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "UninstallString"), 3) $i = $i + 1 Next Next $aSoftwareInfo[0][0] = UBound($aSoftwareInfo, 1) - 1 If $aSoftwareInfo[0][0] < 1 Then SetError(1, 1, 0) Return _ArraySort($aSoftwareInfo,0,1) Endif Endif EndFunc ; ;Function to copy .exe installers to the local C:\temp of the PC the script is executing on. Func _FileList() DirCreate("C:\temp\") FileInstall('C:\Users\me\Desktop\Installers\jre-6u39-windows-x64.exe', 'C:\temp\', 1) FileInstall('C:\Users\me\Desktop\Installers\jre-6u39-windows-i586.exe', 'C:\temp\', 1) FileInstall('C:\Users\me\Desktop\Installers\openvpn-setup-final.exe', 'C:\temp\', 1) EndFunc ; ;Start 32-bit Java install Func _JavaUpdate32() Run("C:\temp\jre-6u39-windows-i586.exe") EndFunc ; ;Start 64-bit Java install Func _JavaUpdate64() Run("C:\temp\jre-6u39-windows-x64.exe") EndFunc ; ;Start OpenVPN install Func _OpenVPN() Run("C:\temp\openvpn-setup-final.exe") EndFunc ; ;Read registry to see if WUpdate is enabled, if not, display a button click to run the relevant function to add registry entries to enable WUpdate. Func _WUpdateRegRead() Local $wupdate = RegRead("HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU", "NoAutoUpdate") If $wupdate <> 0 Then If @OSArch = 'x64' Then Local $w7updategui64 = GUICtrlCreateButton(' Enable Windows Updates ', 50, 615 ) GUICtrlSetOnEvent($w7updategui64, '_W7UpdateRegWrite64') ElseIf @OSArch <> 'x64' Then Local $w7updategui32 = GUICtrlCreateButton(' Enable Windows Updates ', 300, 615 ) GUICtrlSetOnEvent($w7updategui32, '_W7UpdateregWrite32') EndIf EndIf EndFunc ; ;Placeholder for registry entries to enable WUpdate for 64-bit Win 7 Func _W7UpdateRegWrite64() MsgBox(4096, "Enabling Windows Updates", "Applying Windows Update Policies for Windows 7 (64-bit)", 5) EndFunc ; ;Placeholder for registry entries to enable WUpdate for 32-bit Win 7 Func _W7UpdateRegWrite32() MsgBox(4096, "Enabling Windows Updates", "Applying Windows Update Policies for Windows 7 (32-bit)", 5) EndFunc ; Link to comment Share on other sites More sharing options...
iamtheky Posted March 7, 2013 Share Posted March 7, 2013 So the new java installation does not show even under the 'ALL' selection? If you change the $uninstkey to HKLM64 (or just add that key as an additional location to poll and add to the array), do you get different results? ,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-. |(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/ (_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_) | | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) ( | | | | |)| | \ / | | | | | |)| | `--. | |) \ | | `-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_| '-' '-' (__) (__) (_) (__) Link to comment Share on other sites More sharing options...
bigirishape Posted March 8, 2013 Author Share Posted March 8, 2013 I made a quick edit to the script. It runs fine on my machine to report the installed softare, yet when I run it on my test machine, still no report of software installed. Func _ComputerGetSoftware(ByRef $aSoftwareInfo) If @OSArch = "X64" Then $registry = "HKLM" Else $registry = "HKLM64" EndIf Local Const $UnInstKey = $registry & "\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" I can see the registry key where Java is installed. It is directly under "ComputerHKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionUninstall{26A24AE4-039D-4CA4-87B4-2F86416039FF} and the DisplayName entry is "Java 6 Update 39 (64-bit)". It just isn't showing up in the GUI screen. I'm really not sure what is going on. It was working great until I did an uninstall/reinstall of Java, and now the script doesn't even see it in the Registry, but it's right there. Thanks for showing up boththose, I was hoping I'd hear from you Link to comment Share on other sites More sharing options...
iamtheky Posted March 8, 2013 Share Posted March 8, 2013 sorry i am not of more assistance, I have uninstalled and reinstalled 6u43 a couple of times and cannot replicate the issue. If you put msgbox (0, '' , "looking for " & $m[$n] & " inside the string: " & $Reg) after the regread can you determine whether it has even cycled through the java entry. That and maybe comment out the continueloop line to ensure that it is not being skipped. ,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-. |(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/ (_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_) | | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) ( | | | | |)| | \ / | | | | | |)| | `--. | |) \ | | `-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_| '-' '-' (__) (__) (_) (__) Link to comment Share on other sites More sharing options...
bigirishape Posted March 8, 2013 Author Share Posted March 8, 2013 Added the msgbox line and went through the gamut of registry entries and noticed something weird... I have 2 machines, both Windows 7 Enterprise (64-bit) SP1... My primary machine lists Java as installed, but has the registry entry saved in: ComputerHKEY_LOCAL_MACHINESOFTWAREWow6432NodeMicrosoftWindowsCurrentVersionUninstall{26A24AE4-039D-4CA4-87B4-2F83216039FF} My test machine lists Java as *not* installed, but has the registry entry saved in: ComputerHKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionUninstall{26A24AE4-039D-4CA4-87B4-2F86416039FF} The only difference is the uninstall key changes slightly in the last segment, and the keys are stored in the Wow6432Node subkey on the PC that is actually displaying the software as installed, but nowhere in the script does it reference the Wow6432Node subtree... I'm confused... *shakes fist at Bill Gates* Link to comment Share on other sites More sharing options...
bigirishape Posted March 8, 2013 Author Share Posted March 8, 2013 Yeah, the registry has me lost. The script is solid, the registry is the killer.So pointing the script towards "HKLM64SoftwareMicrosoftWindowsCurrentVersionUninstall" reads the key stored in "ComputerHKEY_LOCAL_MACHINESOFTWAREWow6432NodeMicrosoftWindowsCurrentVersionUninstall{26A24AE4-039D-4CA4-87B4-2F83216039FF}" and reports it as installed.It does not read the key stored in "ComputerHKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionUninstall{26A24AE4-039D-4CA4-87B4-2F86416039FF}"Pointing the script towards "HKEY_LOCAL_MACHINESoftwareMicrosoftWindowsCurrentVersionUninstall" does the exact same thing. Link to comment Share on other sites More sharing options...
iamtheky Posted March 8, 2013 Share Posted March 8, 2013 (edited) edit: i am lost as well, so all stabs that follow are into darknesshave you tried disabling redirection? This call seems to fix most of my x86/x64 issues.DllCall("kernel32.dll", "int", "Wow64DisableWow64FsRedirection", "int", 1)http://www.autoitscript.com/autoit3/docs/intro/64-bit_support.htm Edited March 8, 2013 by boththose ,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-. |(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/ (_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_) | | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) ( | | | | |)| | \ / | | | | | |)| | `--. | |) \ | | `-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_| '-' '-' (__) (__) (_) (__) Link to comment Share on other sites More sharing options...
bigirishape Posted March 8, 2013 Author Share Posted March 8, 2013 Yeah, still no dice. So here's another question, more of a logic question than anything... If I were to populate an array called $regpath with both "HKEY_LOCAL_MACHINESOFTWAREWow6432NodeMicrosoft" and "HKEY_LOCAL_MACHINESOFTWAREMicrosoft", how would you recommend I go about looping through that array so I could use "$UnInstKey = $regpath[$r] & "WindowsCurrentVersionUninstall" to get an inventory of both options? I trimmed out everything else, and just trying to lock down this cycle through the array. If I run it, I get my msgbox pop up that says $r = 0, and $UnInstKey = HKEY_LOCAL_MACHINESOFTWAREWow6432NodeMicrosoftWindowsCurrentVersionUninstall....so I know I'm on the right path, I just can't get it to run through the other item in the array... Sorry if this is starting to seem like a coding lesson, but I'm missing something that is probably right in front of my eyes, and I just can't see it... expandcollapse popup#include Opt("TrayAutoPause", 0) Opt('GUIOnEventMode', 1) Opt('GUICloseOnEsc' , 1) Global $i Global $r = 0 Global $m[2] = ["Java", "openvpn"] Global $regpath[2] = ["HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft", "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft"] Local $sSft Global $sGui = GUICreate('Currently Installed Software for ' & @OSVersion & ' ' & @OSArch, 810, 650, -1, -1) Global $sLvw = GUICtrlCreateListView('#|Installed Software|Display Version|Publisher|Uninstall String', 5, 5, 800, 600) _ComputerGetSoftware($sSft) For $i = 1 To ubound($sSft) - 1 GUICtrlCreateListViewItem($i & '|' & $sSft[$i][0] & '|' & $sSft[$i][1] & '|' & $sSft[$i][2] & '|' & $sSft[$i][3], $sLvw) Next GUICtrlSendMsg($sLvw, 0x101E, 1, 175) GUICtrlSendMsg($sLvw, 0x101E, 2, 65) GUICtrlSendMsg($sLvw, 0x101E, 3, 150) GUICtrlSendMsg($sLvw, 0x101E, 4, 350) Local $mMen = GUICtrlCreateContextMenu($sLvw) GUISetOnEvent(-3, '_AllExit') GUISetState(@SW_SHOW, $sGui) While 1 Sleep(10) WEnd ; Func _AllExit() GUIDelete($sGui) Exit EndFunc ; Func _ComputerGetSoftware(ByRef $aSoftwareInfo) Local $i = 1 Local $n = 0 Local $r = 0 Dim $aSoftwareInfo[1][4] $input = inputbox ("Which Software" , "You are running " & @OSVersion & " " & @OSARCH & @CRLF & @CRLF & "Which Software would you like to view, ALL or Some?", 'Some') If @Error = 1 Then Exit If $input = 'ALL' Then For $r = 0 to 1 Local $UnInstKey = $regpath[$r] & "\Windows\CurrentVersion\Uninstall" For $j = 1 To 500 $AppKey = RegEnumKey($UnInstKey, $j) If @error <> 0 Then Exitloop If RegRead($UnInstKey & "\" & $AppKey, "DisplayName") = '' Then ContinueLoop ReDim $aSoftwareInfo[UBound($aSoftwareInfo) + 1][4] $aSoftwareInfo[$i][0] = StringStripWS(StringReplace(RegRead($UnInstKey & "\" & $AppKey, "DisplayName"), " (remove only)", ""), 3) $aSoftwareInfo[$i][1] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "DisplayVersion"), 3) $aSoftwareInfo[$i][2] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "Publisher"), 3) $aSoftwareInfo[$i][3] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "UninstallString"), 3) $i = $i + 1 Next Next $aSoftwareInfo[0][0] = UBound($aSoftwareInfo, 1) - 1 If $aSoftwareInfo[0][0] < 1 Then SetError(1, 1, 0) Return _ArraySort($aSoftwareInfo,0,1) Else IF $input = 'Some' Then For $r = 0 to 1 Local $UnInstKey = $regpath[$r] & "\Windows\CurrentVersion\Uninstall" msgbox (0, '', $r & " " & $UnInstKey) For $n = 0 to 1 For $j = 1 To 500 Local $UnInstKey = $regpath[$r] & "\Windows\CurrentVersion\Uninstall" $AppKey = RegEnumKey($UnInstKey, $j) If @error <> 0 Then Exitloop $Reg = RegRead($UnInstKey & "\" & $AppKey, "DisplayName") ;msgbox (0, '', "looking for " & $m[$n] & " inside the string: " & $Reg) ;msgbox (0, '', "Looking in " & $UnInstKey & " ") $string = stringinstr($Reg, $m[$n]) If $string = 0 Then Continueloop ReDim $aSoftwareInfo[UBound($aSoftwareInfo) + 1][4] $aSoftwareInfo[$i][0] = StringStripWS(StringReplace(RegRead($UnInstKey & "\" & $AppKey, "DisplayName"), " (remove only)", ""), 3) $aSoftwareInfo[$i][1] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "DisplayVersion"), 3) $aSoftwareInfo[$i][2] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "Publisher"), 3) $aSoftwareInfo[$i][3] = StringStripWS(RegRead($UnInstKey & "\" & $AppKey, "UninstallString"), 3) $i = $i + 1 Next Next $aSoftwareInfo[0][0] = UBound($aSoftwareInfo, 1) - 1 If $aSoftwareInfo[0][0] < 1 Then SetError(1, 1, 0) Return _ArraySort($aSoftwareInfo,0,1) Next Endif Endif EndFunc ; Link to comment Share on other sites More sharing options...
Developers Jos Posted March 8, 2013 Developers Share Posted March 8, 2013 The only difference is the uninstall key changes slightly in the last segment, and the keys are stored in the Wow6432Node subkey on the PC that is actually displaying the software as installed, but nowhere in the script does it reference the Wow6432Node subtree...I'm confused... *shakes fist at Bill Gates*Are you using the x86 version of AutoIt3 (AutoIT3.exe) or the x64 version (AutoIt3_x64.exe) when testing? SciTE4AutoIt3 Full installer Download page  - Beta files    Read before posting   How to post scriptsource   Forum etiquette Forum Rules  Live for the present, Dream of the future, Learn from the past. Link to comment Share on other sites More sharing options...
iamtheky Posted March 8, 2013 Share Posted March 8, 2013 Chimaera offered this solution for gathering all potential locations: ,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-. |(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/ (_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_) | | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) ( | | | | |)| | \ / | | | | | |)| | `--. | |) \ | | `-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_| '-' '-' (__) (__) (_) (__) Link to comment Share on other sites More sharing options...
bigirishape Posted March 8, 2013 Author Share Posted March 8, 2013 I figured out one of my issues, it was that I added 2 nested For loops to the Some structure, and neglected to relocate the Return call. I moved it outside of my top level For loop, and it's parsing both registry keys. Now I just need to muddle my way through editing the Array to contain a third field for keeping track of the $regpath[$r] value so that it doesn't spit out the same data in the Array twice. I will also definitely take a look at Chimaera's code. Thanks!! 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