NAME

Win32::EnvProcess - Perl extension to set or get environment variables from other processes

SYNOPSIS

  use Win32::EnvProcess qw(:all);
  
  use Win32::EnvProcess qw(SetEnvProcess); 
  my $result = SetEnvProcess($pid, env_var_name, [value], [...]);
      
  use Win32::EnvProcess qw(GetEnvProcess);
  my @values = GetEnvProcess($pid, [env_var_name, [...]]);
  
  use Win32::EnvProcess qw(DelEnvProcess);
  my $result = DelEnvProcess($pid, env_var_name, [...]);
  
  use Win32::EnvProcess qw(GetPids);
  my @pids = GetPids([exe_name]);

DESCRIPTION

This module enables the user to alter or query an unrelated process's environment variables.

Windows allows a process with sufficient privilege to run code in another process by attaching a DLL. This is known as "DLL injection", and is used here.

NON-STANDARD INSTALLATION STEP

The DLL used for injection is named EnvProcessDll.dll, and does not contain any perl components.

It must be copied to a directory (folder) that is on the load path OF THE TARGET PROCESS. If you are not sure where that is, try C:\Perl\bin (we presumably have perl installed, and it is probably in everyone's path). This is done by the tests by default. Failing that, WINDOWS\system32 should work.

copy .\blib\arch\auto\Win32\EnvProcess\EnvProcessDll.dll some-directory

You do not have to use the command-line for the copy, drag-and-drop with Windows Explorer is probably easier.

EXPORT

None by default.

SetEnvProcess

my $result = SetEnvProcess($pid, env_var_name, [value], ...);

$pid: The process identifier (PID) of the target process. If set to 0 (zero) the parent process identifier is used env_var_name: The name of the environment variable to be set value: The value of the preceeding environment variable

Set one or more environment variables in another process.

The env_var_name/value pairs may be repeated as a list or, more conviently as a hash, with the keys being the environment variable names. You should avoid changing critcal process specific variables such as USERNAME. Also be aware that there is no guarantee that the program will actually use the new value. For example it may have already read the value on start-up and may be holding it internally, the perl interpreter is such a program (see Interaction with perl scripts below).

If an odd number of items is supplied in the list, the final variable specified will have no value. Note that this is not the same as deleting a variable.

Returns: the number of environment variables changed. Error information will be available in $^E (See below).

GetEnvProcess

my @values = GetEnvProcess($pid, [env_var_name, [...]]);

$pid: The process identifier (PID) of the target process. If set to 0 (zero) the parent process identifier is used env_var_name: The name[s] of the environment variable[s] to be read. If not supplied then as many environment variables as possible are returned (see LIMITATIONS below).

Get one or more environment variable values from another process.

Returns undef on error, error information will be available in $^E. If one or more environment variable name are specified, a list of environment variable values is returned. Note that these may be empty strings if no value is set. If a requested variable does not exist then an empty string is returned in it's place in the list, and $^E will be set to 203 (ERROR_ENVVAR_NOT_FOUND).

If no environment variable names are specified then the environment block is returned (subject to LIMITATIONS) in the form of a list. Items are of the form variable=value and may be extracted into a hash as follows:

  @values = GetEnvProcess (0);
  
  my %proc_env;
  for (@values) {
      my ($key, $value) = split /=/;
      $proc_env{$key} = $value;
  }

DelEnvProcess

my $result = DelEnvProcess($pid, env_var_name, ...);

$pid: The process identifier (PID) of the target process. If set to 0 (zero) the parent process identifier is used env_var_name: The name of the environment variable to be deleted

Delete one or more environment variables in another process.

The env_var_name may be repeated as a list. You should avoid deleting critcal process specific variables such as USERNAME and PATH. Also be aware that the program may have already read the value on start-up and may be holding it internally, the perl interpreter is such a program (see Interaction with perl scripts below).

Returns: the number of environment variables deleted. Error information will be available in $^E (See below).

GetPids

my @pids = GetPids([exe_name]);

exe_name: The basename of an executable file (including the '.exe')

If supplied, a case-insensitive match is done between the exe name and running processes. If not supplied, then the identifier of the parent process is returned.

Returns: A list of process-ids of processes running the supplied exe, or zero on error. This function is provided to assist in obtaining the required process id.

Security may prevent some processes from being queried. When this is the case it is unlikely that we have the permissions to manipulate the environment block. The .exe files registered with a process may be in 8.3 format, and currently this function makes no attempt to resolve a 'long name' to short.

$^E ($EXTENDED_OS_ERROR) VALUES

The most likely causes of certain Win32 errors are given below:

8 Not enough storage is available to process this command.

The total data for the environment variables exceeds LIMITATIONS. In this case as much processing as possible will be done.

14 Not enough storage is available to complete this operation.

The number of environment variables exceeds LIMITATIONS

87 The parameter is incorrect.

The supplied PID does not exist

183 Cannot create a file when that file already exists.

Under most circumstances this error may be ignored when correct results are returned. It generally means that more than one process (or thread) is using this module.

186 The flag passed is not correct.

Internal corruption of the FMO, please contact the author

203 The system could not find the environment option that was entered

The requested environment variable does not exist

LIMITATIONS

Total size of variable names and values: 8192 (increased at v.0.05).

Total number of environment variables : 254 (increased at v.0.05).

These are artificial limits and may be made more flexible in a future release.

Locking: the entire sequence is serial because a named FMO is used. Creating the File Mapping Object(FMO), writing to it, and running the DLL in the other process, is protected by a Mutex. It is therefore possible that calls may block.

Interaction with perl scripts

If the target process is a perl script, then note that the script will not 'see' the new variable or value through %ENV. This hash is set at process creation time, and not directly updated through these functions. A perl script can however inspect its own environment using GetProcessEnv with the first argument set to $$.

SEE ALSO

Win2::Env, Env::C

AUTHOR

C. B. Darke, clive.darke@ talk21.com open to suggestions for improvements.

COPYRIGHT AND LICENSE

Copyright (C) 2008 by C. B. Darke

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.6.1 or, at your option, any later version of Perl 5 you may have available.