in reply to Re: [OT] Using Module TieRegistry? for reading and pasting registrykey into another section
in thread [OT] Using Module TieRegistry? for reading and pasting registrykey into another section

I tried the following, but honestly i dont understand much/or nearly nothing of it.
This is an example which i tried to modify
Just how to read a simple value like:
"NoTrack"=dword:00000001
under: HKEY_CURRENT_USER\Software\Microsoft\Office\12.0\Common\General
use Win32::TieRegistry( Delimiter=>"#", ArrayValues=>0 ); $pound= $Registry->Delimiter("/"); $targetKey= $Registry->{"HKEY_CURRENT_USER/Software/Microsoft/Office +/12.0/Common/"} or die "Can't read the key: $^E\n"; $data= $key->{"/General"} or die "Can't read the key: value: $^E\n"; foreach $entry ( keys(%$targetKey) ) { ... } foreach $subKey ( $targetKey->SubKeyNames ) { ... } $targetKey->AllowSave( 1 ); $targetKey->RegSaveKey( "C:/TEMP/testReg", [] );
Error message:
Cant read the key: value: handle is invalid

How do i read a single value from a hash/array? or whatever this is stored when read into the Perl Code in?
Any help welcome
Ty
mh88
  • Comment on Re^2: [OT] Using Module TieRegistry? for reading and pasting registrykey into another section
  • Download Code

Replies are listed 'Best First'.
Re^3: [OT] Using Module TieRegistry? for reading and pasting registrykey into another section
by pryrt (Abbot) on Feb 22, 2018 at 22:16 UTC

    I don't see a .../12.0/Common/General in my registry: I see .../16.0/Common/General, and .../14.0/Common/General, but .../12.0/Common (which does exist in mine) doesn't have a General subkey.

    I think you're getting confused about subkeys vs. values. You have placed the 'general' subkey in a variable called $data. In the Win32::TieRegistry examples,$data holds a value, not a subkey.

    The error you are getting seems to indicate that HKEY_CURRENT_USER\Software\Microsoft\Office\12.0\Common\General does not exist. Since it doesn't exist in my registry, that doesn't surprise me.

    I have built up an SSCCE which uses the 16.0 version, and looks at a value in there (since I don't have the 12.0 'General' subkey)

    #!perl use warnings; use strict; use Data::Dumper; use Win32::TieRegistry( Delimiter => '#', ArrayValues => 0); my $pound = $Registry->Delimiter("/"); my $targetKey = $Registry->{"HKEY_CURRENT_USER/Software/Microsoft/Offi +ce/16.0/Common"} or die "Can't read the 'Common' key: $^E\n"; print STDERR "targetKey = '$targetKey'\n"; # this is the one you + called "data" before. It's not data, it's another key my $generalKey = $targetKey->{"General"} # thhis is another subkey or die "Can't read the 'General' subkey: $^E\n"; print STDERR "generalKey = '$generalKey'\n"; # this is the one y +ou called "data" before. It's not data, it's another key print STDERR Dumper $generalKey; # here, you can access actual values from the key, with or without a p +refixed slash my $data = $generalKey->{'/Authorized'} // '<undef>'; printf STDERR qq("%s" => >>%s<<\n), '/Authorized', $data; my $noslash = $generalKey->{'Authorized'} // '<undef>'; printf STDERR qq("%s" => >>%s<<\n), 'Authorized', $noslash; my $dne = $generalKey->{'DoesNotExist'} // '<undef>'; printf STDERR qq("%s" => >>%s<<\n), 'DoesNotExist', $dne; # update target key to 12.0: $targetKey = $Registry->{"HKEY_CURRENT_USER/Software/Microsoft/Office/ +12.0/Common"} or die "Can't read the '12.0/Common' key: $^E\n"; print STDERR "targetKey = '$targetKey'\n"; # this exists in mine $generalKey = $targetKey->{"General"} or die "Can't read the '12.0/Common/General' subkey: $^E\n"; print STDERR "generalKey = '$generalKey'\n"; # this doesn't exis +t in mine, so it won't get here __END__ generalKey = 'Win32::TieRegistry=HASH(0x26620c8)' $VAR1 = bless( { '/Xlstart' => 'XLSTART', ... '/Authorized' => '0x7FFFFFFF', ... }, 'Win32::TieRegistry' ); "/Authorized" => >>0x7FFFFFFF<< "Authorized" => >>0x7FFFFFFF<< "DoesNotExist" => >><undef><< targetKey = 'Win32::TieRegistry=HASH(0x51e80a8)' Can't read the '12.0/Common/General' subkey: The system cannot find th +e file specified

    I get a different error message than you got... but since you omitted code, who knows what else is different. Try my example, and see what you get. If it works the same, then you can try to tweak the code to make it do what you want.

      use warnings; use strict; use Data::Dumper; #changed the paths to office 12.0 (office 2007) values and the searche +d Key to "SharedTemplates" use Win32::TieRegistry( Delimiter => '#', ArrayValues => 0); my $pound = $Registry->Delimiter("/"); my $targetKey = $Registry->{"HKEY_CURRENT_USER/Software/Microsoft/Offi +ce/12.0/Common"} or die "Can't read the 'Common' key: $^E\n"; print STDERR "targetKey = '$targetKey'\n"; # this is the one you + called "data" before. It's not data, it's another key my $generalKey = $targetKey->{"General"} # this is another subkey or die "Can't read the 'General' subkey: $^E\n"; print STDERR "generalKey = '$generalKey'\n"; # this is the one y +ou called "data" before. It's not data, it's another key print STDERR Dumper $generalKey; # here, you can access actual values +from the key, with or without a prefixed slash my $data = $generalKey->{'/SharedTemplates'} // '<undef>'; printf STDERR qq("%s" => >>%s<<\n), '/SharedTemplates', $data; my $noslash = $generalKey->{'SharedTemplates'} // '<undef>'; printf STDERR qq("%s" => >>%s<<\n), 'SharedTemplates', $noslash; my $dne = $generalKey->{'DoesNotExist'} // '<undef>'; printf STDERR qq("%s" => >>%s<<\n), 'DoesNotExist', $dne; $targetKey = $Registry->{"HKEY_CURRENT_USER/Software/Microsoft/Office/ +12.0/Common"} or die "Can't read the '12.0/Common' key: $^E\n"; print STDERR "targetKey = '$targetKey'\n"; # this exists in mine $generalKey = $targetKey->{"General"} or die "Can't read the '12.0/Common/General' subkey: $^E\n"; print STDERR "generalKey = '$generalKey'\n"; # this doesn't exis +t in mine, so it won't get here

      and a little shortened output:

      C:\temp\strawberry-perl-5.26.0.2-64bit-portable>perl ..\example_code_o +ffice12_3.pl targetKey = 'Win32::TieRegistry=HASH(0x471ae8)' generalKey = 'Win32::TieRegistry=HASH(0x4719c8)' $VAR1 = bless( { '/Xlstart' => 'XLSTART', #just a simple example witho +ut "\" #... shortened #This is what is searched for: '/SharedTemplates' => 'G:\\OFFICE2007\\WORD7\\VORLAGE +N', # ... shortened '/PasteOptions' => '0x00000001' }, 'Win32::TieRegistry' ); "/SharedTemplates" => >>G:\OFFICE2007\WORD7\VORLAGEN<< "SharedTemplates" => >>G:\OFFICE2007\WORD7\VORLAGEN<< "DoesNotExist" => >><undef><< targetKey = 'Win32::TieRegistry=HASH(0x2561ec8)' generalKey = 'Win32::TieRegistry=HASH(0x471ae8)'



      So thats very fine so far. Many thanks we are getting closer :-)
      • Are those "Hexcodes" coded values or are they the "adress where the Field" resides in the registry/Array?
      • The relevant "Key" for me is the SHAREDTEMPLATES -> G:\Office\Word... Path (the other key in the former example was just to try a simplified "non encoded" variant.
      • What does $^E mean? Or where could i read this, which searching text should i have used to find this on my own e.g.?
      Thanks for your patience
      mh88

        Glad it got you closer.

        The "hexcodes" (I assume you mean like the "0x471ae8" in "Win32::TieRegistry=HASH(0x471ae8)") are part of the default stringification of a hashref. They may refer to a memory address, technically, but you cannot use the stringified version of the hashref to access the memory. More, it should be thought of as a unique idenitifier of a particular hash, to which the reference is referring. (Thus, if you have two hashrefs referring to the same hash in memory, they will have the same "hexcodes" in their stringification.)

        "SharedTemplates" is not a key, in Windows registry terminology. It is the name of the value. "General" is a subkey, "SharedTemplates" is the name of a REG_SZ value, and "G:\Office\Word\Vorlagen" is the data in the value named "SharedTemplates". We might not like the Windows registry nomenclature... but we're rather stuck with it at this point.

        Documentation for $^E and other perl builtin variables can be found online at perlvar, or using perldoc perlvar on your command line; perldoc -v '$^E' will give you the info on just that specific variable (use single quotes in linux-like systems or double quotes on the Windows commandline)