MrSparty1995

Issue reading the registry, it's not reading all the sub keys

13 posts in this topic

#1 ·  Posted (edited)

I could use some help with my script, I am looping through the Registry to grab all the java installs to uninstall them.  For some reason, it is skipping all the sub keys that start with {

I have attached 2 pictures.  The first one registry.png, it does not read any of these.  The 2nd one registry2.png, it reads all of those.  I'm sure there is a simple explanation, but I could use some help please.

Here is the code...

 

While 1
   $i = $i + 1

   $var = RegEnumKey("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", $i)
   If @error <> 0 then ExitLoop

   _FileWriteLog($hFile, "The variable is : " & $var)
   ;once you have the next key, now look for Java AND Update
   $tmp = RegRead("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" & "\" & $var,"DisplayName");
   _FileWriteLog($hFile, "The DisplayName is : " & $tmp)
   If stringinstr(RegRead("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" & "\" & $var,"DisplayName"),"Update") then
         ;if it passes both of these ifs, then get the uinstall string
         _FileWriteLog($hFile, "The variable is : " & $var)
         $uis=RegRead("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" & "\" & $var,"UninstallString")
      EndIf
   EndIf
   If $uis <> "" then
      _FileWriteLog($hFile, "***************************")
      _FileWriteLog($hFile, "The uninstall key is : " & $uis)
      _FileWriteLog($hFile, "The actual command we are using now is : " & "MsiExec.exe /X" & $var & " /qn")

      ;MsgBox(4096, "MESSAGE", $uis & " /qn")
      ;if an uninstall string is found, then run the msi uninstall command this retrieved
      ;RunWait($uis & " /qn")
      RunWait("MsiExec.exe /X" & $var & " /qn")
      ;MsgBox(4096, "MESSAGE", "MsiExec.exe /X" & $var & " /qn")
      Sleep(2000)
   EndIf

WEnd

 

registry.PNG

registry2.PNG

Edited by JLogan3o13

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

@MrSparty1995 did you happen to notice the great big bulletin at the top of this forum???

Quote

Do not create AutoIt-related topics here, use the AutoIt General Help and Support or AutoIt Technical Discussion forums.

Moved to the appropriate forum.

Edit: Also added code tags

Regarding your question, it doesn't look like you're accounting for keys that may have a blank DisplayName value. I reworked your code a bit:

#include <File.au3>

Local $sSubkey, $hFile = @DesktopDir & "\Output.log"
Local $sKey = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"


    For $i = 1 To 500
        $sSubkey = RegEnumKey($sKey, $i)
            If @error Then
                ExitLoop
            Else
                _FileWriteLog($hFile, "The variable is : " & $sSubkey)
                $tmp = RegRead($sKey & "\" & $sSubkey,"DisplayName")
                    If $tmp <> "" Then
                        _FileWriteLog($hFile, "The DisplayName is : " & $tmp)
                    Else
                        _FileWriteLog($hFile, "The DisplayName is blank")
                    EndIf
                If StringInStr($tmp,"Update") Then
                    _FileWriteLog($hFile, "The variable is : " & $sSubkey)
                    $uis=RegRead($sKey & "\" & $sSubkey,"UninstallString")
                        If $uis <> "" then
                            _FileWriteLog($hFile, "***************************")
                            _FileWriteLog($hFile, "The uninstall key is : " & $uis)
                            _FileWriteLog($hFile, "The actual command we are using now is : " & "MsiExec.exe /X" & $sSubkey & " /qn")
                        EndIf
                EndIf
            EndIf
    Next

On my system it showed c. 25 keys for which that value is blank. If you're not catching those, it simply won't write anything.

Edited by JLogan3o13

When you're dead, you don't know you're dead - it's only difficult for those that know you. It's the same way when you're stupid...

My Scripts: SCCM UDFInclude Source with Compiled Script, Windows Firewall UDF

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

I don't know why, but I'm still not seeing the java install in the registry.  Does this like right now?  I modified it a little based on your recommendation.

#include <GUIConstants.au3>
#include <Constants.au3>
#include <Array.au3>
#Include <process.au3>
#include <File.au3>
#Include <string.au3>
#include <File.au3>
#NoTrayIcon

Local $hFile = FileOpen("C:\temp\JavaUninstallInstall.log", 1)
_FileWriteLog($hFile, "Attempting to kill processes")
;Close processes
if(ProcessExists("javaw.exe"))   then ProcessClose ("javaw.exe")
if(ProcessExists("frsm.exe"))   then ProcessClose ("frsm.exe")
if(ProcessExists("iexplore.exe"))   then ProcessClose ("iexplore.exe")
if(ProcessExists("java.exe"))   then ProcessClose ("java.exe")
if(ProcessExists("bzmd.exe"))   then ProcessClose ("bzmd.exe")
if(ProcessExists("mcllink.exe"))   then ProcessClose ("mcllink.exe")
Sleep(2000)
_FileWriteLog($hFile, "Done killing processes")
;local variable to get keys from the uninstall directory
Local $i = 0;
Local $uis = "";
Local $tmp = "";
Local $sSubkey
Local $sKey = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
;loop through a while loop, and grab the next key
While 1
   $i = $i + 1

   $sSubkey = RegEnumKey($sKey, $i)
   If @error <> 0 then
      ExitLoop
   Else
      _FileWriteLog($hFile, "The variable is : " & $sSubkey)
      ;once you have the next key, now look for Java AND Update
      $tmp = RegRead($sKey & "\" & $sSubkey,"DisplayName");
      If $tmp <> "" Then
         _FileWriteLog($hFile, "The DisplayName is : " & $tmp)
      Else
         _FileWriteLog($hFile, "The DisplayName is blank")
      EndIf
      If stringinstr(RegRead($sKey & "\" & $var,"DisplayName"),"Java") then
         If stringinstr(RegRead($sKey & "\" & $sSubkey,"DisplayName"),"Update") then
            ;if it passes both of these ifs, then get the uinstall string
            _FileWriteLog($hFile, "The variable is : " & $sSubkey)
            $uis=RegRead($sKey & "\" & $sSubkey,"UninstallString")

            If $uis <> "" then
               _FileWriteLog($hFile, "***************************")
               _FileWriteLog($hFile, "The uninstall key is : " & $uis)
               _FileWriteLog($hFile, "The actual command we are using now is : " & "MsiExec.exe /X" & $sSubkey & " /qn")

               ;if an uninstall string is found, then run the msi uninstall command this retrieved
               ;RunWait("MsiExec.exe /X" & $sSubkey & " /qn")
               ;Sleep(2000)
            EndIf
         EndIf
      EndIf
   EndIf

WEnd

JavaUninstallInstall.log

Edited by JLogan3o13

Share this post


Link to post
Share on other sites

If you're using a 64 bit Windows, and you're running the script as 64 bit, you might have to look in the 32 bit installation keys or vice versa.

 


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

Again, @MrSparty1995, please look at the row of buttons when you post, and use the code tags. Makes it easier for people to help you.

Also, BrewManNH is quite right, I should have pointed out that if you're on a 64bit machine you'll want to check both keys. Something like this:

#include <File.au3>

Local $sSubkey, $sName, $hFile = @DesktopDir & "\Output.log"
Local $sKey = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
Local $s64Key = "HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"

    For $a = 1 To 500
        $sSubkey = RegEnumKey($sKey, $a)
            If @error Then
                ExitLoop
            Else
                $sName = RegRead($sKey & "\" & $sSubkey, "DisplayName")
                    If $sName <> "" Then ConsoleWrite("The DisplayName is : " & $sName & @CRLF)
            EndIf
    Next

    If @OSArch = "X64" Then
        For $b = 1 To 500
            $sSubkey = RegEnumKey($s64Key, $b)
                If @error Then
                    ExitLoop
                Else
                $sName = RegRead($s64Key & "\" & $sSubkey, "DisplayName")
                    If $sName <> "" Then ConsoleWrite("The DisplayName is : " & $sName & @CRLF)
                EndIf
        Next
    EndIf

Alternatively, you could always just use WMI:

$WMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & @ComputerName & "\root\cimv2")
$aItems = $WMI.ExecQuery("SELECT * FROM Win32_Product")

For $element In $aItems
    ConsoleWrite($element.Name & @CRLF)
Next

If Java is what you're after, you could do something like this to automatically call the uninstall:

$WMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & @ComputerName & "\root\cimv2")
$aItems = $WMI.ExecQuery("SELECT * FROM Win32_Product Where Name LIKE '%Java%'")

For $element In $aItems
    ConsoleWrite("Uninstalling: " & $element.Name & @CRLF)
    $element.Uninstall()
Next

 


When you're dead, you don't know you're dead - it's only difficult for those that know you. It's the same way when you're stupid...

My Scripts: SCCM UDFInclude Source with Compiled Script, Windows Firewall UDF

Share this post


Link to post
Share on other sites

Sorry could you explain the code tags, not sure what you mean.

Also you guys were right about the 64, i fixed that, and it picked up the JRE7 Update 80 and uninstalled it.  The problem I've having now, it's not uninstalling JRE8 as well, not sure if that is a wait issue or something else.  Would you recommend I move to WMI and stop using RunWait?

Thanks, James

#include <GUIConstants.au3>
#include <Constants.au3>
#include <Array.au3>
#Include <process.au3>
#include <File.au3>
#Include <string.au3>
#include <File.au3>
#NoTrayIcon

Local $hFile = FileOpen("C:\temp\JavaUninstallInstall.log", 1)
_FileWriteLog($hFile, "Attempting to kill processes")
;Close processes
if(ProcessExists("javaw.exe"))   then ProcessClose ("javaw.exe")
if(ProcessExists("frsm.exe"))   then ProcessClose ("frsm.exe")
if(ProcessExists("iexplore.exe"))   then ProcessClose ("iexplore.exe")
if(ProcessExists("java.exe"))   then ProcessClose ("java.exe")
if(ProcessExists("bzmd.exe"))   then ProcessClose ("bzmd.exe")
if(ProcessExists("mcllink.exe"))   then ProcessClose ("mcllink.exe")
Sleep(2000)
_FileWriteLog($hFile, "Done killing processes")
;local variable to get keys from the uninstall directory
Local $i = 0;
Local $uis = ""
Local $tmp = ""
Local $sSubkey
Local $sKey = "HKLM64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
;loop through a while loop, and grab the next key
While 1
   $i = $i + 1
   ;grab the sub key
   $sSubkey = RegEnumKey($sKey, $i)
   ;if there is an error found doing this, exist, otherwise proceed
   If @error <> 0 then
      ExitLoop
   Else
      ;now for that sub key, get the DisplayName value
      $tmp = RegRead($sKey & "\" & $sSubkey,"DisplayName");
      ;If $tmp <> "" Then
        ; _FileWriteLog($hFile, "The DisplayName is : " & $tmp)
      ;Else
        ; _FileWriteLog($hFile, "The DisplayName is blank")
     ; EndIf
      ;once you have the next key, now look for Java AND Update
      If stringinstr(RegRead($sKey & "\" & $sSubkey,"DisplayName"),"Java") then
         If stringinstr(RegRead($sKey & "\" & $sSubkey,"DisplayName"),"Update") then
            ;if it passes both of these ifs, then get the uninstall string
            ;note we are not using that, since I have noticed from time to time they
            ;have a /I instead of a /X in it
            $uis=RegRead($sKey & "\" & $sSubkey,"UninstallString")

            If $uis <> "" then
               _FileWriteLog($hFile, "***************************")
               _FileWriteLog($hFile, "The uninstall key is : " & $uis)
               _FileWriteLog($hFile, "The actual command we are using now is : " & "MsiExec.exe /X" & $sSubkey & " /qn")

               ;if an uninstall string is found, then run the msi uninstall command this retrieved
               RunWait("MsiExec.exe /X" & $sSubkey & " /qn")
               Sleep(10000)
            Else
               _FileWriteLog($hFile, "Found Java Update but UninstallString is empty")
            EndIf
         EndIf
      EndIf
   EndIf

WEnd

_FileWriteLog($hFile, "Done looking for java")

FileClose($hFile) ; Close the filehandle to release the file.;

Sleep(5000)
;Run 64 bit JRE 1.8.0_51
RunWait("MsiExec.exe /i jre1.7.0_80_x64.msi /qb STATIC=Enable AUTO_UPDATE=Disable REBOOT=Disable WEB_ANALYTICS=Disable WEB_JAVA=Enable WEB_JAVA_SECURITY_LEVEL=H")

RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Update\Policy", "EnableJavaUpdate", "REG_DWORD", "00000000")
RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\JavaSoft\Java Update\Policy", "EnableJavaUpdate", "REG_DWORD", "00000000")
RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\JavaSoft\Java Update\Policy", "EnableAutoUpdateCheck", "REG_DWORD", "00000000")
RegWrite("HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\JavaSoft\Java Update\Policy", "InstalledJREVersion", "REG_SZ", "1.7.0_80")

Exit

Share this post


Link to post
Share on other sites

For the code code this tags:  <>  are used.

10 hours ago, JLogan3o13 said:

 

$WMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & @ComputerName & "\root\cimv2")
$aItems = $WMI.ExecQuery("SELECT * FROM Win32_Product Where Name LIKE '%Java%'")

For $element In $aItems
    ConsoleWrite("Uninstalling: " & $element.Name & @CRLF)
    $element.Uninstall()
Next

 

 

Share this post


Link to post
Share on other sites

Ok thank you, the WMI seems much easier and straight forward.

I do have a question though, I see this in my log(i changed ConsoleWrite to my logging)

2016-09-07 07:25:29 : Uninstalling: Java 8 Update 102 (64-bit)
 

However, it doesn't appear to be removing the directory from the machine, but it does remove it from the registry?

Thanks, James

Share this post


Link to post
Share on other sites

Ok, please IGNORE my question above.

It appears I was running low on space on my machine, and that is why JRE8 was not uninstalling.  Once I cleared up space, I re-ran all of this and it worked.

Thanks all for the comments.

Thanks, James

Share this post


Link to post
Share on other sites

#10 ·  Posted

Quick WMI question now.

This section is working well, however, is there a way to add error checks, to prevent error dialogs from popping up during uninstall?  I have noticed that I had a JRE that didn't install correctly before, when this attempted to uninstall it, it popped up a error dialog that it couldn't find a dll.  Is there a way to prevent this?

Thanks, James

$WMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & @ComputerName & "\root\cimv2")
$aItems = $WMI.ExecQuery("SELECT * FROM Win32_Product Where Name LIKE '%Java%'")

For $element In $aItems
    ConsoleWrite("Uninstalling: " & $element.Name & @CRLF)
    $element.Uninstall()
Next

Share this post


Link to post
Share on other sites

Any ideas?

Share this post


Link to post
Share on other sites

You aren't going to be able to code for every possible eventuality. You can try to catch the error with something like this:

At the top of script:

Global $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc")

At the bottom:

Func _ErrFunc()
    ;write to log file, or do something else.
EndFunc

But if the error is because Java can't find specific files, there's no guarantee that will work. Even if it does mask the error pop up, you will need to figure out some logic to handle these cases.


When you're dead, you don't know you're dead - it's only difficult for those that know you. It's the same way when you're stupid...

My Scripts: SCCM UDFInclude Source with Compiled Script, Windows Firewall UDF

Share this post


Link to post
Share on other sites

Ok thank you.:)

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