I have a small routine that reads code from the registry. This code has worked just fine but today it began giving me trouble. The registry data didn't change. The code that reads it didn't change. I upgraded
Win32::API to version .41 because I needed to use
Win32::API::Struct in another program and immediately began getting this error:
Can't use an undefined value as an ARRAY reference at C:/Perl/site/lib/Win32/TieRegistry.pm line 685, <DATA> line 164.
I'm using Win32::TieRegistry version .24 and actually removed it and re-installed it after the error began but it didn't help. Can this be caused by something that has changed in Win32::API? Probably not but it's the only thing that changed. The compiled (standalone) vserion of this program still works.
Here's the code that reads the registry:
$Key = $Registry->Open( "LMachine/Software/Vibac_Calls/CallsList/F
+ields", {Access=>KEY_READ(),Delimiter=>"/"} ) or warn "OPEN: $Key ->
+(ERROR: $^E)\n";
my @regFields = $Key->SubKeyNames;
$data_mycalls{fields} = ();
for my $x(0..$#regFields)
{
my $fieldKey = $Registry->Open( "LMachine/Software/Vibac_Calls
+/CallsList/Fields/$regFields[$x]", {Access=>KEY_READ(),Delimiter=>"/"
+} ) or warn "OPEN: $Key -> (ERROR: $^E)\n";
#print (join " ", keys %{$fieldKey}) . "\n";
my @regValues = $fieldKey->ValueNames; #THIS IS THE LINE IN MY
+ CODE WHERE THE ERROR APPEARS
for my $y(0..$#regValues)
{
$data_mycalls{fields}[$x]{$regValues[$y]} = $fieldKey->Get
+Value($regValues[$y]);
}
}
When I was trying to debug the problem, I found that the error was being thrown right before calling
ValueNames on the last key. When I added this simple debug line
(that is commented in my code above)
print (join " ", keys %{$fieldKey}) . "\n";
the error went away. It prints the values out as expected and the program continues. There are 7 keys that get looped through and each key has the same 11 values with slightly different data. This problem only happens on the last key. If I add an eighth key with no sub keys, I don't have this problem.
I took a look at Win32::TieRegistry to see where the error came from.
sub _enumValues
{
my $self= shift(@_);
$self= tied(%$self) if tied(%$self);
my( @names )= ();
my $pos= 0;
my $name= "";
my $nlen= 1+$self->Information("MaxValNameLen");
while( $self->RegEnumValue($pos++,$name,$nlen,[],[],[],[]) ) {
push( @names, $name );
}
if( ! _NoMoreItems() ) {
return ();
}
$self->{VALUES}= \@names;
return 1;
}
sub ValueNames
{
my $self= shift(@_);
$self= tied(%$self) if tied(%$self);
@_ and croak "Usage: \@names= \$key->ValueNames;";
$self->_enumValues unless $self->{VALUES};
return @{$self->{VALUES}}; #THIS IS THE LNE THAT THROWS THE ERROR
}
But, of course, I couldn't find anything wrong there either.
Here's an export of the registry in case anyone's interested in seeing the data:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Vibac_Calls\CallsList\Fields]
[HKEY_LOCAL_MACHINE\SOFTWARE\Vibac_Calls\CallsList\Fields\0]
"field"="calls.id"
"header"="ID"
"visible"="1"
"width"="32"
"type"=""
"recordlink"=""
"displaylink"=""
"sort"="ASC"
"sorttype"="number"
"displaypos"="0"
[HKEY_LOCAL_MACHINE\SOFTWARE\Vibac_Calls\CallsList\Fields\1]
"field"="calls.caller"
"header"="Caller"
"visible"="1"
"width"="100"
"type"=""
"recordlink"="users2.id"
"displaylink"="users2.fullname"
"sort"=""
"sorttype"="text"
"displaypos"="1"
[HKEY_LOCAL_MACHINE\SOFTWARE\Vibac_Calls\CallsList\Fields\2]
"field"="calls.responder"
"header"="Responder"
"visible"="0"
"width"="100"
"type"=""
"recordlink"="users2.id"
"displaylink"="users2.fullname"
"sort"=""
"sorttype"="text"
"displaypos"="2"
[HKEY_LOCAL_MACHINE\SOFTWARE\Vibac_Calls\CallsList\Fields\3]
"field"="calls.details"
"header"="Details"
"visible"="1"
"width"="240"
"type"=""
"recordlink"=""
"displaylink"=""
"sort"=""
"sorttype"="text"
"displaypos"="3"
[HKEY_LOCAL_MACHINE\SOFTWARE\Vibac_Calls\CallsList\Fields\4]
"field"="calls.resolution"
"header"="Resolution"
"visible"="1"
"width"="182"
"type"=""
"recordlink"=""
"displaylink"=""
"sort"=""
"sorttype"="text"
"displaypos"="4"
[HKEY_LOCAL_MACHINE\SOFTWARE\Vibac_Calls\CallsList\Fields\5]
"field"="calls.time"
"header"="CallDate"
"visible"="1"
"width"="109"
"type"=""
"recordlink"=""
"displaylink"=""
"sort"="ASC"
"sorttype"="number"
"displaypos"="5"
[HKEY_LOCAL_MACHINE\SOFTWARE\Vibac_Calls\CallsList\Fields\6]
"field"="calls.closed"
"header"="Closed"
"visible"="1"
"width"="40"
"type"="check"
"recordlink"=""
"displaylink"=""
"sort"=""
"sorttype"="number"
"displaypos"="6"