Solved

reading windows regsitry with perl

Posted on 2009-07-09
16
374 Views
Last Modified: 2012-05-07
We have a simple program to read the windows registry:

eval 'use Win32::TieRegistry( Delimiter=>"/");';
 if ($@)
 {
        DEBUG("Could not perform the transaction. Reason is:\n$@\n");
}
$key = $Registry->{"HKEY_LOCAL_MACHINE/SOFTWARE/ODBC/ODBC.INI/"} or $error="ERROR , $^E\n";
DEBUG(" open ini entries from registry : $error \n");

This fails for any key in the registry with teh exception :
DEBUG:   open ini entries from registry : ERROR , The system cannot find the file specified

Who do i keep getting this?
Any help will be much appreaciated
0
Comment
Question by:ranadhir
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 4
  • 4
16 Comments
 
LVL 9

Expert Comment

by:Suhas .
ID: 24812262
Hi ranadhir,
the attached code worked fine for me...
please check at your end.

Cheers...
Suhas

use Win32::TieRegistry;
$Registry->Delimiter("/");
 
$odbc_content = $Registry->{"HKEY_LOCAL_MACHINE/SOFTWARE/ODBC/ODBC.INI/"} or $error="ERROR , $^E\n";
foreach my $odbc_data (keys(%{$odbc_content}))
    {
 
        $odbc_data=~s/^\/+//sg;
        print "$odbc_data\n";
    }

Open in new window

0
 

Author Comment

by:ranadhir
ID: 24812308
dont you need to declare the 'Registry' variable?
0
 
LVL 9

Expert Comment

by:Suhas .
ID: 24812334
No that is called from the Win32::TierRegistry module...

For more details please refer http://search.cpan.org/~adamk/Win32-TieRegistry-0.26/lib/Win32/TieRegistry.pm

Cheers...
Suhas
0
Simplifying Server Workload Migrations

This use case outlines the migration challenges that organizations face and how the Acronis AnyData Engine supports physical-to-physical (P2P), physical-to-virtual (P2V), virtual to physical (V2P), and cross-virtual (V2V) migration scenarios to address these challenges.

 

Author Comment

by:ranadhir
ID: 24813393
Not using eval seems to open up the registry.
However for a sub-node if we again go to access  I get problem again.
How do i access the sub-node?

$key = $Registry->{"HKEY_LOCAL_MACHINE/SOFTWARE/ODBC/ODBC.INI/"} or $error="ERROR , $^E\n";
EMD_PERL_DEBUG(" open ini entries from registry : $error \n");
my @members=keys( %{$key} );
foreach (@members){
if (m/^(.*)\/$/) {
$odbcnode=$key->{$1};//This again gives the same problem
}
0
 
LVL 39

Expert Comment

by:Adam314
ID: 24815323

#!/perl/bin/perl
use strict;
use warnings;
use Data::Dumper;
use Win32::TieRegistry;
$Registry->Delimiter('/');
 
my $key = $Registry->{"HKEY_LOCAL_MACHINE/SOFTWARE/ODBC/ODBC.INI/"}
  or die "Could not get registry entry1: $^E\n";
 
my @members=keys %$key;
foreach (@members){
	print "$_\n";
	next unless /^(.*)\/$/;
	my $odbcnode=$key->{$1};
	print "    " . join("\n    ", keys %$odbcnode) . "\n";
}

Open in new window

0
 
LVL 9

Expert Comment

by:Suhas .
ID: 24815806
since the registry contents are stored in the form of key valyue pairs...
you need to use hashes... to access any entry.
 
0
 

Author Comment

by:ranadhir
ID: 24817944
Bu the constraint here is that I need to use eval to load the win32 module dynamically.
This is part of a code that will be used in both  unix and windows.
Explicitly loading irrespective of platform causes the code to fail in unix - loading via 'eval' causes this particular piece to fail in windows.
0
 
LVL 39

Expert Comment

by:Adam314
ID: 24818281
You could load the module through require, which is similar to use but processed at runtime instead of compile time.
You probably would also be better using $^O to determine if you are on windows.

if($^O eq 'MSWin32') {
    require Win32::TieRegistry;
    #Do whatever here with registry
}
else {
    #Non windows, do whatever
}
 
 
#Or, if you want to use the success/failure of loading Win32::TieRegistry:
eval {
    require Win32::TieRegistry;
    #Do whatever here with registry
};
if($@) {
    #There was an error
}

Open in new window

0
 

Author Comment

by:ranadhir
ID: 24819935
I have tried usnig eval - please refer to code sample in the question.
And that is what is not working.

If I use 'use' to load at compile time - there are no issues;however it restricts my abilities on unix.

Will it be possible to make the same work with 'eval'?
I do not get any exception during load of win32::TieRegistry,however the registry hit fails with a 'System cannot find the file'
0
 
LVL 39

Expert Comment

by:Adam314
ID: 24820164

The require would be more efficient than the eval with a string using 'use', but if this doesn't bother you, then the eval like you have is fine.

Does the code in post 24815323 work?  I tested it, and it worked on my windows computer fine.  What about if you don't remove the trailing slash from the key name?  Instead of this:
    foreach (@members){
        print "$_\n";
        next unless /^(.*)\/$/;
        my $odbcnode=$key->{$1};
        print "    " . join("\n    ", keys %$odbcnode) . "\n";
    }
Try this:
    foreach (@members){
        print "$_\n";
        next unless /^(.*)\/$/;
        my $odbcnode=$key->{$_};
        print "    " . join("\n    ", keys %$odbcnode) . "\n";
    }
0
 

Author Comment

by:ranadhir
ID: 24820214
No.none is working - they all give compilation/runtime errors

What I am trying now:
my $key="";

my regErr="";
$osType = get_osType();     # get the OS type
if($osType eq "WIN")
{
      require Win32::TieRegistry;
      import Win32::TieRegistry;
      $Registry->Delimiter("/");
      $key = $Registry->{"HKEY_LOCAL_MACHINE/SOFTWARE/ODBC/ODBC.INI/"} or $regErr="ERROR , $^E\n";
      DEBUG(" open odbc  registry  node: $regErr \n");
}

Then I used the 'key' within a sub.
sub getDBConnect()
{
....
.....
if($osType eq "WIN")
{
my @members=keys( %{$key} );
foreach (@members){
if (m/^(.*)\/$/) {
.....
.....
}
}
}

This never works - am yet to find what the problem is .
However,if I  do the following - everything works like a song
use Win32::TieRegsitry;
$Registry->Delimiter("/");

And then within my sub:
sub getDBConnect()
{
my key="";
....
.....
if($osType eq "WIN")
{
$key = $Registry->{"HKEY_LOCAL_MACHINE/SOFTWARE/ODBC/ODBC.INI/"} or $regErr="ERROR , $^E\n";
DEBUG(" open odbc  registry  node: $regErr \n");
my @members=keys( %{$key} );
foreach (@members){
if (m/^(.*)\/$/) {
.....
.....
}
}
}

0
 

Author Comment

by:ranadhir
ID: 24820293
What i do find is that it gives
Global symbol '$Registry' requires explicit package name - in the case where i use 'require'.
0
 
LVL 9

Expert Comment

by:Suhas .
ID: 24820328
can you try by placing the require Win32::TieRegistry; at first line of the program...
0
 

Author Comment

by:ranadhir
ID: 24820355
Its all the same - the moment i shift from use win32::TieRegistry to
if($osType eq "WIN")
{
      require Win32::TieRegistry;
      import Win32::TieRegistry;
      $Registry->Delimiter("/");
}
I get symbol resolution erros for $Registry
0
 

Accepted Solution

by:
ranadhir earned 0 total points
ID: 24820463
l will use the fully qualified name now -$Win32::TieRegistry::Registry
0
 
LVL 39

Expert Comment

by:Adam314
ID: 24823938
Sorry, forgot to add that with require, you need to call the import to get the $Registry variable.
    require Win32::TieRegistry;
    Win32::TieRegistry->import();

0

Featured Post

U.S. Department of Agriculture and Acronis Access

With the new era of mobile computing, smartphones and tablets, wireless communications and cloud services, the USDA sought to take advantage of a mobilized workforce and the blurring lines between personal and corporate computing resources.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Can I legally transfer my OEM version of Windows to another PC?  (AKA - Can I put a new systemboard in my OEM PC?) Few of us are both IT and legal experts but we all have our own views of Microsoft's licensing rules and how they apply.  There are…
cPanel is a Unix based web hosting control panel that provides a graphical interface and automation tools designed to simplify the process of hosting a web site. cPanel utilizes a 3 tier structure that provides functionality for administrators, rese…
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…

733 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question