Permalink
Fetching contributors…
Cannot retrieve contributors at this time
97 lines (80 sloc) 3.66 KB
# -*- coding: utf-8 -*-
import os
import sys
from ctypes import windll
from ctypes import cdll
from ctypes import c_wchar_p
from ctypes.util import find_msvcrt
def _putenv(name, value):
'''
:param name: environment variable name
:param value: environment variable value
This function ensures that changes to an environment variable are applied
to each copy of the environment variables used by a process. Starting from
Python 2.4, os.environ changes only apply to the copy Python keeps (os.environ)
and are no longer automatically applied to the other copies for the process.
On Microsoft Windows, each process has multiple copies of the environment
variables, one managed by the OS and one managed by the C library. We also
need to take care of the fact that the C library used by Python is not
necessarily the same as the C library used by PyGTK and friends. This because
the latest releases of PyGTK and friends are built with mingw32 and are thus
linked against msvcrt.dll. The official GTK+ binaries have always been built
in this way.
'''
# Update Python's copy of the environment variables
os.environ[name] = value
# Update the copy maintained by Windows (so SysInternals Process Explorer sees it)
try:
result = windll.kernel32.SetEnvironmentVariableW(c_wchar_p(name), c_wchar_p(value))
if result == 0: raise Warning
except Exception:
if sys.flags.verbose:
sys.stderr.write('* pygtk-runtime: "kernel32.SetEnvironmentVariableW" failed\n')
sys.stderr.flush()
else:
if sys.flags.verbose:
sys.stderr.write('* pygtk-runtime: "kernel32.SetEnvironmentVariableW" successful\n')
sys.stderr.flush()
# Update the copy maintained by msvcrt (used by GTK+ runtime)
try:
result = cdll.msvcrt._putenv('%s=%s' % (name, value))
if result != 0: raise Warning
except Exception:
if sys.flags.verbose:
sys.stderr.write('* pygtk-runtime: "msvcrt._putenv" failed\n')
sys.stderr.flush()
else:
if sys.flags.verbose:
sys.stderr.write('* pygtk-runtime: "msvcrt._putenv" successful\n')
sys.stderr.flush()
# Update the copy maintained by whatever c runtime is used by Python
try:
msvcrt = find_msvcrt()
msvcrtname = str(msvcrt).split('.')[0] if '.' in msvcrt else str(msvcrt)
result = cdll.LoadLibrary(msvcrt)._putenv('%s=%s' % (name, value))
if result != 0: raise Warning
except Exception:
if sys.flags.verbose:
sys.stderr.write('* pygtk-runtime: "%s._putenv" failed\n' % msvcrtname)
sys.stderr.flush()
else:
if sys.flags.verbose:
sys.stderr.write('* pygtk-runtime: "%s._putenv" successful\n' % msvcrtname)
sys.stderr.flush()
if sys.platform == 'win32' or sys.platform == 'nt':
RUNTIME = os.path.abspath(os.path.join(os.path.dirname(__file__), 'bin'))
PATH = os.environ['PATH'].split(os.pathsep)
ABSPATH = [os.path.abspath(x) for x in PATH]
if ABSPATH[0] != RUNTIME:
if sys.flags.verbose:
sys.stderr.write('* pygtk-runtime: prepending "%s" to PATH\n' % RUNTIME)
sys.stderr.write('* pygtk-runtime: original PATH="%s"\n' % os.pathsep.join(PATH))
sys.stderr.flush()
PATH.insert(0, RUNTIME)
_putenv('PATH', os.pathsep.join(PATH))
if sys.flags.verbose:
sys.stderr.write('* pygtk-runtime: modified PATH="%s"\n' % os.pathsep.join(PATH))
else:
if sys.flags.verbose:
sys.stderr.write('* pygtk-runtime: "%s" already on PATH\n' % RUNTIME)
sys.stderr.flush()