slloyd has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to capture the registry changes made by a software installation but am not having much success. My thought was to capture the registry using Win32::TieRegistry before and after the install and compare them. Butthe code below says no changes were made to the registry during install (I verified that the reg keys were made).

According to the Win32::TieRegistry documentation, I can call the Flush() method to Flush "all cached information about the Registry key so that future uses will get fresh data from the Registry." But for some reason, my $LmRegAfter is the same as my $LmRegBefore. Any suggestions would be appreciated.

use strict; use Win32::TieRegistry ( Delimiter=>"/", ArrayValues=>0 ); #snapshot registry before install my $LmRegBefore = $Registry->{"LMachine/Software/"}; #Run the installation program - much harder in real life, but this is +a test script :) my $install='path to install to run'; system($install); #Flush the reg subkey my $r=$Registry->{"LMachine/Software/"}->Flush(); print ("Flushing LMachine[$r]"); #snapshot registry after install my $LmRegAfter = $Registry->{"LMachine/Software/"}; registryChanges($LmRegBefore,$LmRegAfter); ############# sub registryChanges{ my $regBefore=shift; my $regAfter=shift; foreach my $key (keys(%{$regAfter})){ if(!defined $regBefore->{$key}){ my $val=$regAfter->{$key}; $change{$key}=$val; print "registryChanges[$key]=[$val]\n"; } } }

Replies are listed 'Best First'.
Re: Capturing Win32 registry changes made by a software installation
by massa (Hermit) on Sep 01, 2008 at 15:36 UTC
    I think you are storing a reference to that registry, and not a "deep copy" of the contents of the registry. Try this (I can't test b/c no Win here):
    use strict; use Storable q(dclone); use Win32::TieRegistry ( Delimiter=>"/", ArrayValues=>0 ); #snapshot registry before install my $LmRegBefore = dclone $Registry->{"LMachine/Software/"}; #Run the installation program - much harder in real life, but this is +a test script :) my $install='path to install to run'; system($install); #Flush the reg subkey my $r=$Registry->{"LMachine/Software/"}->Flush(); print ("Flushing LMachine[$r]"); #snapshot registry after install my $LmRegAfter = dclone $Registry->{"LMachine/Software/"}; registryChanges($LmRegBefore,$LmRegAfter);
    []s, HTH, Massa (κς,πμ,πλ)
      Great idea but it did not make any difference.

      -------------------------------
      Sign up now for a free monthly newsletter service!
      http://www.bestgazette.com

Re: Capturing Win32 registry changes made by a software installation
by BrowserUk (Patriarch) on Sep 01, 2008 at 16:25 UTC
Re: Capturing Win32 registry changes made by a software installation (unflush)
by tye (Sage) on Sep 01, 2008 at 15:28 UTC

    You are assuming that simply opening $LmRegBefore will cause the entire contents of that subtree to be read and cached. That would be slow and hog memory, which is why the documentation doesn't say that that happens.

    - tye        

Re: Capturing Win32 registry changes made by a software installation
by ldln (Pilgrim) on Sep 01, 2008 at 18:42 UTC
    I would use the reg.exe tool to export required keys before and after install, then just do text line by line comparison of those two files with perl (trivial).
    reg export HKLM\Software before.txt --install program-- reg export HKLM\Software after.txt

    Also you might want to convert these files from utf-16 to utf-8 with iconv like this:
    iconv -f utf-16 -t utf-8 before.txt > before_utf8.txt

    (or do it with perl's Encode module)

Re: Capturing Win32 registry changes made by a software installation
by GrandFather (Saint) on Sep 01, 2008 at 21:34 UTC

    A sanity check on the registry operations is that on typical systems they should take significant time - registry tends to be big. If they aren't taking significant time (a few seconds at least I'd guess), then I suspect you need to manually make a deep copy of the registry structure and compare copies.

    Another non-Perl option that may be worth considering is InstallWatch which will catch more than just registry changes, but can take a while to run and need a fair chunk of disk space.


    Perl reduces RSI - it saves typing
Re: Capturing Win32 registry changes made by a software installation
by Anonymous Monk on Sep 01, 2008 at 15:22 UTC
    Basic debugging, print the data after first registry read. Then print the data after you flush.

    I think whats happening is that $LmRegBefore and $LmRegAfter get flushed (because they're the same).