in reply to Win32 GetEnvironmentVariables?

Presuming you're using ActiveState's port, Look in the Win32 (not Win32::API) module for Win32::ExpandEnvironmentStrings(STRING) To quote the documentation:

[EXT] Takes STRING and replaces all referenced environment variable names with their defined values. References to environment variables take the form %VariableName%. Case is ignored when looking up the VariableName in the environment. If the variable is not found then the original %VariableName% text is retained. Has the same effect as the following:

$string =~ s/%([^%]*)%/$ENV{$1} || "%$1%"/eg

back to swampyankee... Incidentally, the built-in %ENV hash should work, except that hashes are case sensitive, but Windows' environment variables are not: $ENV{fred} and $ENV{FRED} are not the same hash elements, but Win32::ExpandEnvironmentStrings('fred') will refer to the same variable as Win32::ExpandEnvironmentStrings('FRED').

Update:  Thanks to ikegami for pointing out that %ENV is magical, at least on Windows

emc

At that time [1909] the chief engineer was almost always the chief test pilot as well. That had the fortunate result of eliminating poor engineering early in aviation.

—Igor Sikorsky, reported in AOPA Pilot magazine February 2003.

Replies are listed 'Best First'.
Re^2: Win32 GetEnvironmentVariables?
by ikegami (Patriarch) on Nov 10, 2006 at 22:38 UTC

    It's true that hash keys are case-sensitive for normal hashes, but %ENV is magical.

    >perl -e "print $ENV{OS} Windows_NT >perl -e "print $ENV{os} Windows_NT

    Furthermore, the correct usage of Win32::ExpandEnvironmentStrings is Win32::ExpandEnvironmentStrings('%VAR%').

    >perl -e "use Win32; print Win32::ExpandEnvironmentStrings('OS') OS >perl -e "use Win32; print Win32::ExpandEnvironmentStrings('%OS%') Windows_NT >perl -e "use Win32; print Win32::ExpandEnvironmentStrings('OS=%OS%') OS=Windows_NT

    There is a difference between %ENV and Win32::ExpandEnvironmentStrings.

    >echo %VAR% %OS% >perl -e "print $ENV{var} %OS% >perl -e "use Win32; print Win32::ExpandEnvironmentStrings('%VAR%') Windows_NT

    Update: Added 2nd and 3rd para.

      Thanks...I never knew that.

      emc

      At that time [1909] the chief engineer was almost always the chief test pilot as well. That had the fortunate result of eliminating poor engineering early in aviation.

      —Igor Sikorsky, reported in AOPA Pilot magazine February 2003.
      but %ENV is magical
      %ENV appears to be magical only under shells where the lookup and expansion of environmental variables is a case-insensitve operation.

      $ set comspec ComSpec=C:\WINDOWS\system32\cmd.exe $ echo %comspec% C:\WINDOWS\system32\cmd.exe $ echo %COMSPEC% C:\WINDOWS\system32\cmd.exe $ perl -le "print 'comspec : ', $ENV{comspec}" comspec : C:\WINDOWS\system32\cmd.exe $ perl -le "print 'COMSPEC : ', $ENV{COMSPEC}" COMSPEC : C:\WINDOWS\system32\cmd.exe
      On systems (shells rather) where there is a distinction between the case-sensitivity of Env. Vars, %ENV behaves rather normally like a hash should.
      $ set | grep -i ^shell shell /bin/tcsh $ echo $shell /bin/tcsh $ echo $SHELL $ perl -le 'print "shell : ", $ENV{shell}' shell : $ perl -le 'print "SHELL : ", $ENV{SHELL}' SHELL : /bin/bash
      It's likely %ENV is tied (I am guessing) or has mechanism similar to tie associated with it to pass lookups to an underlying system call. It should be noted that not all environmental varaibles are populated into %ENV and in other cases, the values of %ENV contradict those of the shell (as shown above). Don't rely too heavily on information or its validity presented to you in %ENV;

      There is a difference between %ENV and Win32::ExpandEnvironmentStrings.

      %ENV holds literals (just like the shell, in most cases atleast), Win32::ExpandEnvironmentStrings() tests the expansion of a literal in the win32 environment and returns it after substituting values defined for the current user.
      $ set var var=%OS% $ perl -MWin32 -e "print $ENV{var} .= ' evaled' , ' => ', Win32::Expa +ndEnvironmentStrings($ENV{var})" %OS% evaled => Windows_NT evaled
      For the purposes of delayed expansion in the environment, Win32::ExpandEnvironmentStrings() then takes a literal string of the form !Foo! rather than %Foo%.
      $ set var=Foo $ set var var=Foo $ set var=Bar & perl -MWin32 -e "print Win32::ExpandEnvironmentStrings +('%var%')" Foo $ set var var=Bar $ set var=Baz & perl -MWin32 -e "print Win32::ExpandEnvironmentStrings +('!var!')" Baz $ set var var=Baz

        It's likely %ENV is tied (I am guessing) or has mechanism similar to tie associated with it to pass lookups to an underlying system call

        That mechanism is called "magic". Tied variables are a specific kind (MG_TYPE) of magical variables.

        %ENV appears to be magical only under shells where the lookup and expansion of environmental variables is a case-insensitve operation.

        It is my understanding that %ENV is magical on all platforms. The magic translates access to %ENV into C library calls.

        To see if %ENV is magical, run

        perl -MDevel::Peek -e 'Dump \%ENV, 1'

        On Windows, that outputs

        SV = RV(0x183a4ec) at 0x2251d8 REFCNT = 1 FLAGS = (TEMP,ROK) RV = 0x225db4 SV = PVHV(0x229584) at 0x225db4 REFCNT = 2 FLAGS = (SMG,RMG,SHAREKEYS) IV = 29 NV = 0 MAGIC = 0x182a964 <---- MG_VIRTUAL = &PL_vtbl_env MG_TYPE = PERL_MAGIC_env(E) ARRAY = 0x18257cc (0:13, 1:11, 2:6, 3:2) hash quality = 102.6% KEYS = 29 FILL = 19 MAX = 31 RITER = -1 EITER = 0x0

        I don't have access to a unix machine at the moment.

        Perl probably doesn't even care whether the env vars are case-sensitive or not. That's probably handled by the C library or passed on the OS.