2010-01-21 15 views
6

Tengo un instalador de Perl de 32 bits. Al usar esto, necesito poder instalar y desinstalar aplicaciones de 32 y 64 bits.¿Cómo hago para que el Perl de 32 bits lea el registro de Windows de 64 bits?

La instalación de 32 y 64 bits está bien. Desinstalar 32 bits también está bien.

Sin embargo, tengo un problema al desinstalar las aplicaciones de 64 bits.

La aplicación solo conoce el nombre de la aplicación como se ve en Agregar Eliminar programas en el panel de control. Por ejemplo, podría ser "Winzip 14.0", que es el nombre para mostrar de Winzip.

Utilizo el siguiente enfoque para la desinstalación: atravieso HKLM/Software/Microsoft/Windows/CurrentVersion/Uninstall y analizo las claves presentes allí para ver si Winzip está haciendo la correspondencia. Si es así, obtengo la cadena de desinstalación desde allí.

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

Si la aplicación es una instalación de 64 bits, entonces la información de desinstalación residen en HKLM/Software/Microsoft/Windows/CurrentVersion/Uninstall.

Sin embargo, el código de instalador Perl dado anteriormente es tratar de leer de HKLM/Software/WOW6432Node/Microsoft/Windows/CurrentVersion/Uninstall
y no encuentra la instalación allí.

Entonces, ¿cómo hago que el código Perl se ejecute en un proceso de 32 bits para leer el valor de registro encontrado en la sección de 64 bits? Soy consciente de la API RegOpenKey() que toma el parámetro KEY_WOW64_64KEY. Pero dado que es una API de Windows, no sé si eso ayudará. Incluso entonces, ¿hay alguna otra alternativa?

+0

posible duplicado de [Lectura del registro de Windows en Perl] (http://stackoverflow.com/questions/30269931/reading-from-windows-registry-in-perl) –

Respuesta

2

Sí, tiene que usar KEY_WOW64_64KEY, no hay otra solución para un proceso de 32 bits. Llamar a la API de Win32 directamente desde Perl parece posible, a juzgar por this web page.

2

También podría llamar la herramienta de registro directamente, en lugar del archivo por lotes:

$WINDIR/system32/reg.exe 

Esta es la ubicación predeterminada para reg.exe cuando se incluye con el sistema operativo.

$WINDIR/sysnative/reg.exe 

Esta es la ubicación virtual del reg.exe nativo de 64 bits cuando se ejecuta desde un proceso de 32 bits.

+0

Puede pasar el '/ reg: 64 'o'/reg: 32' cambie a reg.exe, para evitar especificar una ruta explícita al reg.exe de 32 bits o de 64 bits: https://support.microsoft.com/en-us/kb/ 948698. Entonces solo necesita preocuparse por el tipo de clave (que probablemente debería saber) y no por el tipo de Perl instalado (que presumiblemente no debería importarle). – Ben

1

Como nota en su pregunta, es posible 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, pero en estos días es mejor utilizar TieRegistry's object functions, que envuelve la funcionalidad para que sea más fácil trabajar con el registro:

#!/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"; 

Esto da resultados como se esperaba, tanto para el de 32 bits y 64 -bit claves, y además debería funcionar de la misma manera tanto en 32 bits como en 64 bits Perl (en teoría de todos modos).

Nota: Necesitaba especificar el espacio de nombre completo para la función KEY_READ() en mi versión de Perl para evitar errores de compilación, y no estoy seguro de si hay valores con nombre para las constantes 0x0100 y 0x0200, por lo tanto Es posible que esto sea más lindo. ¡Pero funciona!


(Adaptado de my solution to my question about not being able to read the registry, preguntó antes de que yo sabía que mi problema estaba relacionado con 64 bits vs 32 bits).

Cuestiones relacionadas