Search notes:

Perl module Win32::TieRegistry

The $Registry variable

#!/usr/bin/perl
use warnings;
use strict;
use feature 'say';

use Win32::TieRegistry;

#
#   Win32::TieRegistry creates a variable $Registry which is a VIRTUAL root above
#   of all registry trees (Such as HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE etc)
#
#   Make sure it does indeed exist!
#
die unless $Registry;

#   Each regstry key is identified by a name that differs, however, from
#   the known HKEY_* names:
say for keys (%$Registry);
# Classes\
# LMachine\
# CConfig\
# CUser\
# Users\
# PerfData\
# DynData\
Github repository PerlModules, path: /Win32/TieRegistry/$Registry.pl

Two rules

In order to unambiguously distinguish between keys and values, there are two rules:
This can lead to paths with two adjacent delimiters, eg HKEY_CURRENT_USER/Environment//PATH.

Showing a a particular registry value

#!/usr/bin/perl
use warnings;
use strict;
use feature 'say';

use Win32::TieRegistry(Delimiter=>'/');

my $path_value = $Registry->{'CUser/Environment//PATH'};

#   Does rule «prepend value with delimiter» always have to
#   be followed? It doesn't seem so:
die unless $path_value eq $Registry->{'CUser/Environment/PATH'};

#   Alternative way to get value:
die unless $path_value eq $Registry->{CUser}->{Environment}->{PATH};

say for (split ';', $path_value);
Github repository PerlModules, path: /Win32/TieRegistry/show-value.pl

Showing a key's subkeys

#!/usr/bin/perl
use warnings;
use strict;
use feature 'say';

use Win32::TieRegistry(Delimiter=>'/');

my $path_value = $Registry->{'CUser/Environment//PATH'};

#   Does rule «prepend value with delimiter» always have to
#   be followed? It doesn't seem so:
die unless $path_value eq $Registry->{'CUser/Environment/PATH'};

#   Alternative way to get value:
die unless $path_value eq $Registry->{CUser}->{Environment}->{PATH};

say for (split ';', $path_value);
Github repository PerlModules, path: /Win32/TieRegistry/show-value.pl

Determining if a path is a key, a value or neither

#!/usr/bin/perl
use warnings;
use strict;
use Win32::TieRegistry(Delimiter => '/');

determine('HKEY_CURRENT_USER/Environment');
determine('HKEY_CURRENT_USER/Environment/PATH');
determine('HKEY_CURRENT_USER/Environment/does-not-exist');

sub determine {
  my $path = shift;

  if (my $key_ = $Registry->Open($path)) {
     print "$path is a key\n";
     return;
  }

  if (exists $Registry->{$path}) {
     printf "$path is a value: %s\n", substr($Registry->{$path}, 0, 50);
     return
  }

  print "$path is neither\n";
}
Github repository PerlModules, path: /Win32/TieRegistry/determine-if-key-or-value.pl

Add company and product under HKCU/Software

use warnings;
use strict;

use Win32::TieRegistry (Delimiter=>'/');

my $companyName ="TQ84";
my $productName ="perlTest";
my $softwareKey ="HKEY_CURRENT_USER/Software";


my $companyKey;
my $productKey;


# does company exist in registry?
$companyKey = $Registry->{"$softwareKey/$companyName"};
if (defined $companyKey) {

  print "I found Company $companyName in registry\n";

  $productKey=$Registry->{"$softwareKey/$companyName/$productName"};

  if (defined $productKey) {
    print "Found product $productName, too\n";
  }
  else {
    print "But, I did not find $productName\n";
    $productKey = $Registry->{"$softwareKey/$companyName/$productName"}={};
  }
}
else {
  
  print "I did not find $companyName in registry\n";
  $Registry->{"$softwareKey/$companyName"}={};

  # also, create product:
  $productKey = $Registry->{"$softwareKey/$companyName/$productName"}={};
}


# printing existing values
foreach my $k (keys %$productKey) {
  print "$k = $productKey->{$k}\n";
}

# setting the default value:
$productKey->{'/'} = "new default value";

# setting some other values:
$productKey->{'test_val_1'} = "7";
$productKey->{'test_val_2'} = 42;
$productKey->{'test_val_3'} = "0x470";
Github repository PerlModules, path: /Win32/TieRegistry/add-company-and-or-product.pl

Another script …

use warnings;
use strict;

use Win32::TieRegistry (Delimiter => '/');

my $reg_vars = $Registry->{'HKEY_CURRENT_USER/Environment'};

print "\nShowing variables\n";
for my $var_with_slash (keys %{ $reg_vars } ) {
  my $var = substr($var_with_slash, 1);
  print "$var = " . $reg_vars->{$var_with_slash} . "\n";
}


print "\n\nCreating a few values in the registry (probably needs admin rights under LMachine)\n";
$Registry -> {"LMachine/Software/TQ84/"} = { #"foo" or die $!;
    "foo/" => {
          "x" => "42.42",
          "y/" => {
              "some-text"   => 'Some Text',
              "some-binary" => [ pack("ccc", 16, 32, 48), "REG_BINARY" ],
              "some-dword"  => [ "0x0005", "REG_DWORD" ],
          },
          "z/" => {
              "more-text"       => "abc",
              "even-more-text"  => "def",
          },
     },
     "bar/" => {
          "a" => "aaa aaa",
     },
     "baz" => 'baaaz'
   } or die $!;


print "\nStarting regedit to see the changes\n";
# http://stackoverflow.com/a/12516008/180275
$Registry -> {'HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/Applets/Regedit/LastKey'} = 'Computer\HKEY_LOCAL_MACHINE\SOFTWARE\TQ84';

system ('regedit');

print "\nDeleting the TQ84 key\n";
delKey("LMachine/Software/TQ84/");
system ('regedit');

sub delKey {

  my $regKey = shift;

  for my $k (keys %{$Registry -> {$regKey}}) {
    if (substr($k, -1) eq '/') {
       delKey ("$regKey$k");
       delete $Registry -> {"$regKey$k"}; 
    }
    else {
      delete $Registry -> {"$regKey$k"};
    }
  }

  delete $Registry -> {$regKey};

}
Github repository PerlModules, path: /Win32/TieRegistry/script.pl

See also

registry
Perl modules
op-reg-at.pl: A Perl script to open the Windows registry at a particular key.

Index