2010-01-21 1 views
6

У меня есть 32-разрядный установщик perl. Используя это, мне нужно иметь возможность устанавливать и удалять 32- и 64-разрядные приложения.Как сделать 32-разрядный Perl читать 64-разрядный реестр Windows?

Установка 32- и 64-разрядных в порядке. Деинсталляция 32-разрядной версии тоже в порядке.

Однако у меня возникла проблема при удалении 64-разрядных приложений.

Приложение просто знает имя приложения, как показано в разделе «Добавить» Удалить программы на панели управления. Например, это может быть «Winzip 14.0», который является отображаемым именем для Winzip.

Я использую следующий подход для деинсталляции: я перехожу к HKLM/Software/Microsoft/Windows/CurrentVersion/Uninstall и разбираю присутствующие там ключи, чтобы узнать, соответствует ли Winzip. Если так, я получаю строку удаления оттуда.

my $register = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"; 
    $HKEY_LOCAL_MACHINE->Open($register,$hKey)|| die $!; 
    #Then parse all the nodes and fetch the uninstall string 

Если приложение является 64-разрядной установкой а, то информация о деинсталляции будет находиться в HKLM/Software/Microsoft/Windows/CurrentVersion/Uninstall.

Однако Вышеприведенный Perl код установки пытается прочитать из HKLM/Software/WOW6432Node/Microsoft/Windows/CurrentVersion/Uninstall
и он не находит установку там.

Как сделать код Perl, запущенный в процессе 32_bit, для чтения значения реестра, найденного в 64-битном улье? Я знаю API RegOpenKey(), который принимает параметр KEY_WOW64_64KEY. Но поскольку это Windows API, я не знаю, поможет ли это. Даже тогда есть ли другая альтернатива?

+0

Возможный дубликат [Чтение из реестра Windows в Perl] (http://stackoverflow.com/questions/30269931/reading-from-windows-registry-in-perl) –

ответ

2

Да, вы должны использовать KEY_WOW64_64KEY, нет другого способа обхода решения для 32-битного процесса. Вызов API Win32 прямо из Perl представляется возможным, судя по this web page.

2

Можно также вызвать инструмент рег непосредственно, вместо пакетного файла:

$WINDIR/system32/reg.exe 

Это местоположение по умолчанию для reg.exe, когда в комплекте с операционной системой.

$WINDIR/sysnative/reg.exe 

Это виртуальное расположение исходного 64-разрядного reg.exe при выполнении из 32-разрядного процесса.

+0

Вы можете передать '/ reg: 64 'или'/reg: 32' в reg.exe, чтобы избежать указания явного пути к 32-разрядному или 64-разрядному reg.exe: https://support.microsoft.com/en-us/kb/ 948698. Тогда вам нужно только заботиться о типе ключа (который вы, вероятно, знаете), а не о том, какой тип Perl установлен (что вам, по-видимому, не стоит заботиться). – Ben

1

Как вы заметили в своем вопросе, можно specify a 64-bit or 32-bit registry views with the KEY_WOW64_64KEY flag.

The old Win32API::Registry can specify the 64-bit registry with KEY_WOW64_64KEY, но в эти дни лучше использовать TieRegistry's object functions, который оборачивает функциональность, чтобы сделать его проще работать с реестром:

#!/usr/bin/perl -w 
use strict; 
use Win32::TieRegistry (Delimiter => '/'); 

print "registry 64-bit:\n"; 
my $mykey = new Win32::TieRegistry 
    'HKEY_LOCAL_MACHINE/Software/Microsoft/Windows/CurrentVersion/Uninstall', 
    { Access=>Win32::TieRegistry::KEY_READ()|0x0100, Delimiter=>'/' }; 

print "\tValues are:\n"; 
print join("\n\t\t", $mykey->ValueNames); 
print "\n"; 

#Getting a specific value's value 
#$mykeyval = $mykey->GetValue('Path'); 

print "\tFiltered subkeys are:\n\t\t"; 
print join("\n\t\t", grep(!/\{[-A-Fa-f0-9]+\}/, $mykey->SubKeyNames)); 
print "\n"; 

print "registry 32-bit explicit:\n"; 
$mykey = new Win32::TieRegistry 
    'HKEY_LOCAL_MACHINE/Software/Microsoft/Windows/CurrentVersion/Uninstall', 
    { Access=>Win32::TieRegistry::KEY_READ()|0x0200, Delimiter=>'/' }; 

print "\tValues are:\n\t\t"; 
print join("\n\t\t", $mykey->ValueNames); 
print "\n"; 

#Getting a specific value's value 
#$mykeyval = $mykey->GetValue('Path'); 

print "\tFiltered subkeys are:\n\t\t"; 
print join("\n\t\t", grep(!/\{[-A-Fa-f0-9]+\}/, $mykey->SubKeyNames)); 
print "\n"; 

Это дает результаты, как ожидается, как для 32-битных и 64 -битные ключи, а также должны работать одинаково как в 32-битном, так и в 64-битном Perl (теоретически в любом случае).

Примечание: Мне нужно указать полное пространство имен для функции KEY_READ() в моей версии Perl, чтобы предотвратить ошибки компиляции, и я не уверен, есть ли именованные значения для констант 0x0100 и 0x0200, так что это возможно, это может быть красивее. Но это работает!


(адаптировано из my solution to my question about not being able to read the registry, спросил, прежде чем я знал, что моя проблема была связана с 64-битным против 32-бит).

Смежные вопросы