Robust environment variables on Windows

Arjen Markus (14 March 2003) Many of my company's programs rely on the presence of environment variables. Sometimes because third-party packages do, sometimes to find our own configuration files, sometimes because the operating system uses them to find the shared/dynamic libraries. (See Extending the DLL Search Path on Windows)

It has been a great sorrow to me that full-scale installation scripts are needed to make such simple things possible as extending the PATH variable under Microsoft Windows and that if you need to do it manually, you have to open any of a wildly varying collection of windows to achieve what you want. It seems so much simpler under Unix. And I have never had "out of environment space" issues there.

The other day, I suddenly realised that there is no need to set these variables in the arcane ways of Windows: just use a small Tcl script. Using Tclkit has additional advantages:

  • No need to install Tcl separately
  • No DOS box appearing

So, instead of defining MYVAR and extending PATH in the System panel, or whatever it is called today, just do:

   set ::env(MYVAR) "Whatever"
   lappend ::env(PATH) "c:/myprogramdir"

   exec myprog.exe &

When the exec command completes, the script is ended and so is Tclkit. But my program is running ...

MHo: This is because the newly executed myprog.exe inherits the environment table from its parent process. P.S.: You don't have to struggle with windows dialogs to manipulate the environment permanently; take a look at the setx.exe-Utility from the resource-kit.


More on this subject appears in, for example, "Setting environment variables with a script", and the remarks here [L1 ] by GWL and Ralf Fassel.


tombert - 2016-04-27 12:34:31

If one does not want to add a static library search path to the PATH environment variable, based on the above restart approach one can also do the following. Check on which platform you are running: windows, 32 bit or 64 bit. Create the additional library path to search for (in the example below it is in the share/lib32 or share/lib64 sub-path of the executable). If the path is not found in the current PATH environment restart the whole script.

I build this code because of dependency issues with my tdbc::postgres compilation. In the lib32 and lib64 path I put the libpq, libintl-8 ... libs.

## add lib32/lib64 library search path to environment
if {$tcl_platform(platform) == "windows"} {
    if {$tcl_platform(pointerSize) == 4} {
        set libPath [file join [file dirname [file dirname [info nameofexecutable]]] share lib32]
    } else {
        set libPath [file join [file dirname [file dirname [info nameofexecutable]]] share lib64]
    }
    set found 0
    foreach path [split $::env(PATH) ";"] {
        set path [file normalize $path]
        if {$path == $libPath} {set found 1}
    }
    if {!$found} {
        append ::env(PATH) ";[file nativename $libPath]"
        exec [info nameofexecutable] [info script] &
        exit
    }
}