Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Win32API::Registry -- RegOpenKeyEx fails when called 2 times.

by ashah21 (Initiate)
on Mar 12, 2010 at 06:44 UTC ( #828220=perlquestion: print w/ replies, xml ) Need Help??
ashah21 has asked for the wisdom of the Perl Monks concerning the following question:

In the code below, if the first sub key SOFTWARE\\ActiveState\\ActivePerl does not exist then it fails to get the second key as well even if the second key exists. It works fine only if both keys exist. Please help.



#!/usr/bin/env perl -w use strict; use Win32API::Registry 0.21 qw( :ALL ); &main; sub getRegistryKeys { my ($hKey,$sKey,$sValue) = @_; my ($type, $data, $error, $key); RegOpenKeyEx( $hKey, $sKey, 0, KEY_READ, $key) or warn "Can't ope +n $hKey\\$sKey: ", regLastError(),"\n"; $error = regLastError(); print "\nError after open: $error"; return "error" if ($error ne ""); RegQueryValueEx( $key, $sValue, [], $type, $data, [] ) or warn "C +an't read $hKey\\$sKey: ", regLastError(),"\n"; $error = regLastError(); print "\nError after query: $error"; if ($error ne ""){ RegCloseKey( $key ) or warn "Can't close $hKey\\$sKey: ", reg +LastError(),"\n"; return "error"; } RegCloseKey( $key ) or warn "Can't close $hKey\\$sKey: ", regLast +Error(),"\n"; return "error" if ($error ne ""); return $data; } sub main { my $ret; $ret = getRegistryKeys(HKEY_LOCAL_MACHINE,"SOFTWARE\\ActiveState\\ +ActivePerl1","CurrentVersion"); if ($ret =~ /error/) { print "\nFound error in first attemp..."; $ret = getRegistryKeys(HKEY_LOCAL_MACHINE,"SOFTWARE\\ActiveSta +te\\PerlScript\\1.0","InstallDir"); print "\nSecond attemp: $ret"; } else { print $ret; } }


Output of the script:

Can't open 2147483650\SOFTWARE\ActiveState\ActivePerl: The system cannot find the file specified

Error after open: The system cannot find the file specified

Found error in first attemp...

Error after open: The system cannot find the file specified

Second attemp: error

Comment on Win32API::Registry -- RegOpenKeyEx fails when called 2 times.
Download Code
Re: Win32API::Registry -- RegOpenKeyEx fails when called 2 times. (subkey ne value)
by tye (Cardinal) on Mar 12, 2010 at 07:23 UTC

    Your presentation is a bit confusing, but it appears to me that it fails the same way both times. So you provide no evidence that "2 times" has anything to do with your problem.

    My guess is simply that CurrentVersion is a subkey of LMachine/Software/ActiveState/ActivePerl, not a value. If so, that would make sense why trying to open a value named "CurrentVersion" would give you the "not found" error.

    - tye        

Re: Win32API::Registry -- RegOpenKeyEx fails when called 2 times.
by cdarke (Prior) on Mar 12, 2010 at 11:27 UTC
    I got exactly the same error, but I would expect it since I do not have an ActivePerl1 key. If I replace the ActivePerl1 with ActivePerl then it works for me - sort of.

    Your "error" traces look for an error even when there is none. You should only call regLastError when a function fails, that is returns false. You are calling in some cases without testing the return code.
Re: Win32API::Registry -- RegOpenKeyEx fails when called 2 times.
by afoken (Parson) on Mar 12, 2010 at 13:37 UTC

    Two quotes from the very beginning of the Win32::Registry documentation:

    obsolete, use Win32::TieRegistry

    and

    NOTE: This module provides a very klunky interface to access the Windows registry, and is not currently being developed actively. It only exists for backward compatibility with old code that uses it. For more powerful and flexible ways to access the registry, use Win32::TieRegistry.

    So, why don't you just use Win32::TieRegistry?

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

      Heh. That's funny. You are quoting Win32::Registry documentation to somebody who is using Win32API::Registry. So, understandably, most of what you quoted doesn't apply very well here.

      But much of what you quoted may appear to apply here (and the spirit of your advice is certainly reasonable), so let's use this as an opportunity to spread some knowledge about the Perl Win32 Registry modules.

      This module provides a very klunky interface

      The interface Win32API::Registry provides is substantially similar to that of Win32::Registry and is certainly, at least in some ways, more clunky than the interface of Win32::TieRegistry. But the interface of Win32API::Registry is basically just the Microsoft interface.

      The main difference between Win32::Registry and Win32API::Registry (and the reason for the "API" in the name) is that the latter sticks very closely to the underlying interface (for several important reasons). One big reason is to prevent a common problem I find in so many XS modules, that of the XS module being (sometimes significantly) less powerful than the underlying interface that the module is supposed to be wrapping and/or exposing. The only "use" of the included API calls that I allowed myself to prevent was causing a "core dump" (a dated term from a different operating system but still the one I prefer as a generic term for what happens when a process violates basic sanity rules and the operating system is forced to "take it down" for everybody's protection).

      I was actually able to use the Win32API::Registry's interface to explore the Microsoft Registry interface very thoroughly in order to fill in details about the underlying interface that were undocumented, vaguely documented, or confusingly documented by Microsoft. My documentation for Win32API::Registry should have been mostly a transcription of Microsoft's documentation, since the interface was nearly identical (very slightly more Perlish) and the same functionality was provided.

      But I found that the number of questions raised by my reading of the Microsoft documentation tended to be on the same order of magnitude as the number of questions answered by it. The Microsoft documentation proved significantly insufficient as a source when writing the module documentation. But I found the Perl debugger and my module together made a very fast and easy playground for exploring the Microsoft interface and answering my own questions.

      and is not currently being developed actively

      To be frank, Win32API::Registry is not under anything close to "active development". And neither is Win32::TieRegistry. I continue to try to change that, having a bunch of fixes and improvements already made that need to be merged together between each other and other changes that have been made to those modules by others who volunteered to patch up some problems (mostly dealing with newer versions of Perl). The work has gotten badly fragmented due to so many moves over the decade-plus.

      It only exists for backward compatibility with old code that uses it.

      There was extra work done to Win32::Registry quite a while after I'd effectively (as far as I was concerned, at least) replaced it. So it isn't just for backward compatibility.

      In contrast, the reason for Win32API::Registry was to provide a full-power tool that could be used to implement a much friendlier (and much more Perlish) tool, Win32::TieRegistry. But Win32API::Registry is still a useful tool in its own right.

      There are several reasons one might choose to use Win32API::Registry instead of or in addition to Win32::TieRegistry. One might already be quite comfortable with the Microsoft interface (despite its pronounced non-Perlish nature). One might be trying to become more comfortable with that interface. And, there are some things that can't be done directly in the friendlier Win32::TieRegistry interface (which, of course, can be done via Win32API::Registry). For that last case, I tend to do the easy steps via TieRegistry and only use Win32API::Registry routines (which can be used via TieRegistry objects) for the particular "advanced" steps.

      For more powerful and flexible ways to access the registry, use Win32::TieRegistry.

      But, barring the above reasons, I agree that one is usually better off just using Win32::TieRegistry.

      - tye        

        Heh. That's funny. You are quoting Win32::Registry documentation to somebody who is using Win32API::Registry.

        <homer>D'oh!</homer> And I was wondering why the version numbers were so different ...

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

      Well I tried Win32::TieRegistry also but it is not working on IA64 machine. While Win32API::Registry is able to get the key values on IA64 machine as well. Not sure if I was missing anything.

      use Win32::TieRegistry( Delimiter=>"#", ArrayValues=>0 ); $pound= $Registry->Delimiter("/"); $swKey= $Registry->{"HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Internet Ex +plorer/"} or die "Can't read LMachine/System/Disk key: $^E\n"; $data= $swKey->{"/Version"} or die "Can't read LMachine/System/Disk// +Information value: $^E\n"; print "\n........data::$data";

      Same code works fine on x86 machine while fails on IA64.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://828220]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (6)
As of 2014-07-12 15:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When choosing user names for websites, I prefer to use:








    Results (240 votes), past polls