2010-10-01 1 views
1

Я хочу, чтобы иметь возможность установить переменную среды системы в Perl, и я написал следующий скрипт (вдохновленный от this idea) для выполнения этого:Как установить переменную системной среды Win32 в 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_; 

Однако, я не являюсь экспертом в Perl, и я хотел бы знать, что эксперты думают об этом коде. Это лучший способ добиться этого?

+6

Я не являюсь экспертом в любой Perl или Windows. Я рекомендую (а также экспертам) «использовать строгие» и «использовать предупреждения» в вашем коде. Это считается хорошей практикой и сэкономит ваше время. –

+1

В Unix вы используете '$ ENV {VARIABLENAME} =" выбранное значение ";'. Я не знаю, почему не нужно делать то же самое в Windows, но отчасти это зависит от того, что вы подразумеваете под «переменной системной среды». Я подозреваю, что вы можете пытаться вмешаться в реестр. Для этого вам понадобятся точные данные от других. –

+1

@Jonathan. По переменной системной среды я имею в виду переменные среды, которые вы найдете в Свойствах компьютеров> Дополнительно> Переменные окружения> Система. Эти переменные сохраняются даже после перезапуска системы; Однако, если мы делаем $ ENV {VARIABLENAME} = "выбранное значение", то эта переменная действительна только для текущего сеанса. – Santhosh

ответ

3

Другой возможный подход:

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

Я думаю, что код Сантхоша лучше, так как WMI - это способ, рекомендованный Microsoft. Кроме того, он короче. Во всяком случае, +1 для WM_SETTINGCHANGE, который не будет известен тем, кого соблазняет прямая манипуляция реестром. – dolmen

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

  • Нет связанных вопросов^_^