2010-10-01 3 views
1

Je veux être en mesure de définir une variable d'environnement système en Perl et moi avons écrit le script suivant (inspiré de this idea) pour y parvenir:Comment définir une variable d'environnement système Win32 en Perl?

use Win32; 
use Win32::API; 
use Win32::OLE qw(in); 

my $machine = "."; 
my $WMIServices = Win32::OLE->GetObject ("winmgmts:{impersonationLevel=impersonate,(security)}//$machine/root/cimv2") || die; 

my $objVariable = $WMIServices->Get("Win32_Environment")->SpawnInstance_; 
$objVariable->{Name}="NewOSType"; 
$objVariable->{UserName} = "<System>"; 
$objVariable->{VariableValue} = "LAMBDA"; 
$objVariable->Put_; 

Cependant, je ne suis pas un expert en Perl et je voudrais savoir ce que les experts pensent de ce code. Est-ce la meilleure façon d'accomplir cela?

+6

Je ne suis pas un expert en soit Perl ou Windows. Je recommande (de même que les experts) d'utiliser des avertissements "stricts" et "d'utilisation" dans votre code. Cela est considéré comme une bonne pratique et vous fera gagner du temps. –

+1

Sous Unix, vous faites '$ ENV {VARIABLENAME} =" valeur choisie ";'. Je ne connais pas de raison de ne pas faire de même sur Windows, mais cela dépend en partie de ce que vous entendez par "variable d'environnement système". Je soupçonne que vous essayez d'altérer le registre à la place. Pour cela, vous aurez besoin d'une contribution précise des autres. –

+1

@Jonathan, Par variable d'environnement système, j'entends les variables d'environnement que vous trouvez dans Propriétés de l'ordinateur> Avancé> Variables d'environnement> Système. Ces variables sont conservées même après un redémarrage du système; Cependant, si nous faisons un $ ENV {VARIABLENAME} = "valeur choisie", alors cette variable n'est valide que pour la session en cours. – Santhosh

Répondre

3

Une autre approche possible:

use strict; 
use warnings; 
use Win32::TieRegistry qw[:KEY_]; 
use Win32::API; 
use constant HWND_BROADCAST => -1; 
use constant WM_SETTINGCHANGE => 0x1a; 

my $hklm_env = Win32::TieRegistry->new(
    'HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Session Manager/Environment', 
    { Access => KEY_READ() | KEY_WRITE(), Delimiter => '/' } 
); # returns undef if SYSTEM ENV not writable 

my $hkcu_env = Win32::TieRegistry->new(
    'HKEY_CURRENT_USER/Environment', 
    { Access => KEY_READ() | KEY_WRITE(), Delimiter => '/' } 
); 

# if SYSTEM ENV not writable try USER ENV 
my $e = defined($hklm_env) ? $hklm_env : $hkcu_env; 

if(defined $e) { 
    $e->SetValue('Variable', 'Value'); 
} 
else { 
    warn "Cannot open neither SYSTEM ENV nor USER ENV registry for Read+Write"; 
} 

my $SendMessage = new Win32::API("user32", "SendMessage", 'NNNP', 'N') or die "Couldn't create SendMessage: $!\n"; 
my $RetVal = $SendMessage->Call(HWND_BROADCAST,WM_SETTINGCHANGE,0,'Environment'); 
+0

Je pense que le code de Santhosh est meilleur que WMI est recommandé par Microsoft. En outre, il est plus court. Quoi qu'il en soit, +1 pour le WM_SETTINGCHANGE qui ne serait pas connu de ceux qui sont tentés par une manipulation directe du registre. – dolmen

Questions connexes