Perl's TieRegistry и Windows Server 2008 R2 - PullRequest
       12

Perl's TieRegistry и Windows Server 2008 R2

0 голосов
/ 25 октября 2009

У нас есть программа на Perl, которая до сих пор хорошо работала на всех платформах Windows.

Когда мы попробовали это на недавно выпущенной Windows Server 2008 R2, она перестала работать. Расследование показало, что проблема в том, что вызовы для чтения значений реестра с помощью TieRegistry возвращали неопределенные значения.

Это известная проблема? Кто-нибудь сталкивался с проблемой доступа к реестру на Windows Server 2008 R2 с помощью TieRegistry? Я запускаю программу от имени администратора, поэтому не думаю, что это проблемы с разрешениями. Программа отлично работает и правильно читает реестр на Windows 7 и Vista.

Пример сценария, который я написал для доступа к реестру, также не работает:

use Win32::TieRegistry(Delimiter=>'\\');
my $reg = "HKEY_LOCAL_MACHINE\\SOFTWARE\\TEST\\Value1";
my $val = $Registry->{$reg};
print "val: ".$val."\n";

Любая помощь будет оценена.

Спасибо, шина

Ответы [ 4 ]

2 голосов
/ 07 августа 2012

Так как Google любит придумывать это, когда люди ищут решение, я решил оставить небольшую заметку.

Вам не нужно изменять TieRegistry.pm, чтобы это работало. Все, что вам нужно сделать, это добавить параметр «Доступ» к вызову. Вот пример:

my $rk = Win32::TieRegistry->new('LMachine\Software\Microsoft\Microsoft SQL Server\Instance Names\SQL', {Access=> 0x20019|0x0200});

Над ORd есть два флага вместе:

0x20019  -- Read access to keys
0x0200   -- Access the 64 bit version of registry (ignored on 32 bit systems)

Вы также можете использовать 0x0100 для доступа к 32-битной версии реестра с перенаправлением (также игнорируется в 32-битных системах)

Таким образом, вам не нужно изменять библиотеку, и одна программа может получить доступ к ОБА версиям реестра.

1 голос
/ 26 октября 2009

Я нашел источник моей проблемы.

Чтобы TieRegistry хорошо работал на 64-битной Windows и имел доступ к правильному кусту реестра, мы использовали решение , предложенное Тони Б. Окусанья (также цитируемое здесь ). Однако это решение добавляет к параметру доступа и KEY_WOW64_64KEY, и KEY_WOW64_32KEY, что не логично - либо вы хотите получить доступ к 64-битному реестру и использовать KEY_WOW64_64KEY, либо вы хотите 32-битный реестр и использовать KEY_WOW64_32KEY. Использование обоих не имеет никакого смысла.

Тем не менее, в предыдущих версиях Windows, а также Windows 7 , кажется, что когда RegOpenKeyEx замечает, что флаг KEY_WOW64_64KEY установлен в параметре access, он использует 64 реестр и игнорирует флаг KEY_WOW64_32KEY. Windows Server 2008 R2 , с другой стороны, не игнорирует флаг KEY_WOW64_32KEY, и, если установлены оба флага, открытие раздела реестра завершается неудачно, и Win32API::Registry.regLastError возвращает ошибку The parameter is incorrect.

Удаление |KEY_WOW64_32KEY из нашего измененного TieRegistry.pm решило проблему и заставило наше приложение снова работать.

С уважением,

splintor

0 голосов
/ 22 сентября 2014

Это работает для меня

use Win32::TieRegistry (
ArrayValues => 0,
SplitMultis => 1, AllowLoad => 1,
 qw(:KEY_), Delimiter => '/', FixSzNulls => 1
);

use constant KEY_WOW => (uc($ENV{PROCESSOR_ARCHITECTURE}) eq "AMD64" || uc($ENV{PROCESSOR_ARCHITEW6432}) eq "AMD64") ? 0x100 : 0x200;

$Registry->Open('LMachine/Software/Microsoft/',{Access => KEY_READ | KEY_WOW});
0 голосов
/ 24 августа 2012

Это моя первая публикация здесь. Вот решение, которое я придумал, и пример его использования:

use Win32::TieRegistry( Delimiter=>"#", ArrayValues=>0 );
my $pound              = $Registry->Delimiter("/");
my $fileSep            = "\\"; 
my $path               = "";
my $PerlBin            = "";
my $PerlInstallDir     = "";
my $PerlInstallDrive   = "";
my $SybaseInstallDir   = "";
my $SybaseInstallDrive = "";


# Standard syntax for access to 32-bit registry
my $regKey = $Registry->{"HKEY_LOCAL_MACHINE/SOFTWARE/Perl"};   
print "\n\n\n" . "Accessing 32 bit registry for Perl Info:" ."\n\n\n";
foreach $key (keys %$regKey){
    print"$key: " . $regKey->{"$key"} . "\n";
}

$path = $regKey->{"/"};
$PerlInstallDir = Win32::GetShortPathName($path);
$path = $regKey->{"/BinDir"};
$PerlBin = Win32::GetShortPathName($path);
$PerlInstallDrive  = substr($PerlInstallDir, 0, 2) . $fileSep;

print "\n\n\n" . "Accessing 64 bit registry for Sybase Info:" ."\n\n\n";

 # This syntax passes the HEX flag to access the 64 bit registry
$regKey = $Registry->Open("HKEY_LOCAL_MACHINE/SOFTWARE/SYBASE/Setup", {Access=> 0x20019|0x0100});
foreach $key (keys %$regKey){
    print"$key: " . $regKey->{"$key"} . "\n";
}
$path = $regKey->{"/SYBASE"};
$SybaseInstallDir = Win32::GetShortPathName($path);
$SybaseInstallDrive = substr($SybaseInstallDir, 0, 2) . $fileSep;


print "\n\n\nFinished retrieving registry info:" . "\n";
print "Perl executable Location  == $PerlBin" . "\n";
print "Perl Install Drive        == $PerlInstallDrive" . "\n";
print "Perl Install Directory    == $PerlInstallDir" . "\n";
print "Sybase Install Drive      == $SybaseInstallDrive" . "\n";
print "Sybase Install Directory  == $SybaseInstallDir" . "\n";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...