Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?

access 64bit registry from 32 bit Perl

by anaconda_wly (Scribe)
on Dec 04, 2012 at 14:35 UTC ( #1007098=perlquestion: print w/replies, xml ) Need Help??
anaconda_wly has asked for the wisdom of the Perl Monks concerning the following question:

I'm exporting registry table using a batch file only contains one line below:

REGEDIT /e C:\reg.reg HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\

When I call system from 32 compiled perl to run the batch file :


I'm still automatically redirected to the Wow6432Node I didn't want. What can I do?When I run the command on cmd.exe instead of in Perl, that's just what I want.

I have to say, the WOW64 is very inconvenient for sript writer. Calling Win API from script is much inconvenient, opposed as in C++.

From my case, though my perl is 32 bit(I have to use 32bit Perl), I initiate a system Perl function such as in C++ to call an external command, a batch file, which I deliberately try walking around the 32bit caller.

I'm using win7.

Replies are listed 'Best First'.
Re: access 64bit registry from 32 bit Perl
by GrandFather (Sage) on Dec 05, 2012 at 03:08 UTC

    I use the following sub to grovel through registry looking for installers which may be of interest to you:

    sub FindXXXSoftware { my ($resetNoModify) = @_; return if !$^O eq 'MSWin32'; my @result; eval { require 'Win32/'; require 'Win32/'; require 'Win32API/'; my $pathPrefix = 'LMachine\SOFTWARE'; my $wowPath = 'Wow6432Node'; my $pathSuffix = 'Microsoft\Windows\CurrentVersion\Uninstall'; my $root = Win32::TieRegistry->new($pathPrefix, {Access => Win32API::Registry::KEY_READ()}); my @products; for my $subPath ($pathSuffix, "$wowPath\\$pathSuffix") { my $uninstall = $root->Open($subPath); next if !$uninstall; $uninstall->Flush(); my @entries = $uninstall->SubKeyNames(); for my $entry (@entries) { my $entryKey = $uninstall->Open($entry); my $name = $entryKey->GetValue('DisplayName'); my $pub = $entryKey->GetValue('Publisher'); my $noModify = $entryKey->GetValue('NoModify'); next if !defined $name || !defined $pub || $pub !~ /^XXX/i; eval { delete $entryKey->{NoModify}; return 1; } or warn "Registry DeleteValue failed for 'NoModify' agains +t $name\n" if defined $noModify && $resetNoModify; push @result, {entryCode => $entry, name => $name}; } } return 1; }; return @result; }
    True laziness is hard work

      Thanks for your code.

      It took me some time to understand. But sorry maybe I didn't catch the point, for I didn't see how you resolve the problem of 32bit program accessing a 64bit program's registry in 64bit OS

      In fact, any trying of accessing to "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" will be redirected to "HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\" automatically. That means I can never get content of "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" branch, which is what I want using a 32bit Perl program and different from "HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\"

      The Perl code I wrote is like what you have written somewhat, but didn't work as I wished. I spent a lot of time to check why I didn't get the correct content as seeing from regedit. Later I understand by searching websites that the WoW64 is doing the redirecting...

        I had a similar problem and solved it like:
        use Win32API::Registry qw(:ALL); ... if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Cryptograp +hy", 0, KEY_READ|0x0100, $key ) ) { RegQueryValueEx($key, "MachineGuid", [], $type, $nodeId, []); RegCloseKey( $key ); }
        The point is 'KEY_READ|0x0100'. From
        #define KEY_WOW64_64KEY 0x0100 Access a 64-bit key from either a 32-bit or 64-bit application.
Re: access 64bit registry from 32 bit Perl
by bulk88 (Priest) on Dec 05, 2012 at 02:12 UTC
    Google says you need to call the 64 bit version of regedit. You are calling the 32 bit version probably.
      I had run the two versions of regedit on command line. I found the 32bit regedit.exe didn't contain "Wow6432Node" at all, the 64 bit version provide that node. As my program export always "Wow6432Node" node into the .reg file, I don't think what I called is a 32 bit version.
        I dont understand what you want to do. You have a .reg file, that needs to be applied, without redirection, to the registry? Then use the 64bit regedit. If your .reg file is getting the redirection, then you are calling the 32 bit regedit. You have to use an absolute path with "Sysnative" folder (google it) in it to reach the 64 bit regedit from a 32 bit perl.
      I can't find "windows/sysnative" folder on both my win7 and win2k3(64bit). I only see "sysWOW64" in Winodws folder.
        goto C:\WINDOWS\SysWOW64 in explorer, double click on cmd.exe,
        Microsoft Windows [Version 5.2.3790] (C) Copyright 1985-2003 Microsoft Corp. C:\WINDOWS\SysWOW64>cd .. C:\WINDOWS>cd Sysnative C:\WINDOWS\Sysnative>
        Only 32 bit processes can see it. It doesn't exist in a 64 bit process. Server 2003 x64 used for above example (I did apply the MS patch to enable sysnative on server 2003 btw). If I try a normal (64 bit) cmd.exe I get
        C:\WINDOWS>cd Sysnative The system cannot find the path specified. C:\WINDOWS>

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1007098]
Front-paged by bulk88
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (9)
As of 2017-08-23 20:23 GMT
Find Nodes?
    Voting Booth?
    Who is your favorite scientist and why?

    Results (358 votes). Check out past polls.