2009-01-28 4 views
7

Kann ich im Anschluss an meine previous question ein Python-Skript erstellen, das eine Windows-Umgebungsvariable ständig ändert?Kann ein Python-Skript eine Windows-Umgebungsvariable ständig ändern? (elegant)

Änderungen an os.environ bleiben nicht bestehen, sobald der Python-Interpreter beendet wird. Wenn ich dies auf UNIX-Scripting wurde, könnte ich so etwas wie:

set foo=`myscript.py` 

Aber leider hat cmd.exe nichts hat, die wie sh Rücken-tick Verhalten funktioniert. Ich habe eine sehr langatmige Lösung gesehen ... es aint ziemlich so sicher können wir auf diese verbessern:

for /f "tokens=1* delims=" %%a in ('python ..\myscript.py') do set path=%path%;%%a 

sicherlich die Köpfe bei Microsoft eine bessere Lösung als diese haben!

Hinweis: genaue Kopie von this question.

+0

Ich denke nicht, die Frage ist eine exakte Kopie, da meine Frage Windows geht. –

Antwort

1

Ihre langatmige Lösung ist wahrscheinlich die beste Idee; Ich glaube nicht, dass dies von Python direkt möglich ist. Dieser Artikel schlägt einen anderen Weg, eine temporäre Batch-Datei:

http://code.activestate.com/recipes/159462/

+5

Das ändert die Umgebung nicht nachhaltig. Es ändert lediglich eine Kopie der Umgebungsvariablen. – ralphtheninja

+0

Das ist was ich will! –

+2

@Salim Fadhley Wenn du das willst, warum fragst du dann etwas anderes in deiner Frage? Indem Sie die Antwort annehmen, die die Frage nicht beantwortet, führen Sie Leute irreführend, die nach Informationen suchen ... –

5

Sie könnten Python Win32 Extensions, entwickelt von Mark Hammond versuchen wollen, die in der ActivePython enthalten ist (oder kann separat installiert werden). In Hammond's and Robinson's book können Sie lernen, wie viele Windows-verwandte Aufgaben ausgeführt werden.

Mit PyWin32 zuzugreifen Fenster COM-Objekte kann ein Python-Programm die Environment Property des WScript.Shell Objekt verwenden - eine Sammlung von Umgebungsvariablen.

3

Windows legt Umgebungsvariablen aus Werten fest, die für jeden Prozess unabhängig voneinander in der Registrierung gespeichert sind.

Es gibt jedoch ein Tool in der Windows XP Service Pack 2 Support Tools namens setx.exe, mit dem Sie globale Umgebungsvariablen über die Befehlszeile ändern können.

+4

setx.exe ist auch mit Vista installiert. Ich habe jedoch den Eindruck, dass das ursprüngliche Poster tatsächlich herausfinden wollte, wie man die Umgebung des Elternprozesses ändert, und nicht, dass Umgebungsvariablenwerte über Neustarts hinweg erhalten bleiben. – bk1e

3

Meine Lösung mit win32api:

import os, sys, win32api, win32con 
'''Usage: appendenv.py envvar data_to_append''' 
def getenv_system(varname, default=None): 
    ''' 
    Author: Denis Barmenkov <barmenkov at bpc.ru> 

    Copyright: this code is free, but if you want to use it, 
       please keep this multiline comment along with function source. 
       Thank you. 

    2006-01-28 15:30 
    ''' 
    v = default 
    try: 
     rkey = win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE, 'SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment') 
     try: 
      v = str(win32api.RegQueryValueEx(rkey, varname)[0]) 
      v = win32api.ExpandEnvironmentStrings(v) 
     except: 
      pass 
    finally: 
     win32api.RegCloseKey(rkey) 
    return v 

#My set function 
def setenv_system(varname, value): 
    try: 
     rkey = win32api.RegOpenKeyEx(win32con.HKEY_LOCAL_MACHINE, 'SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment',0 ,win32con.KEY_WRITE) 
     try: 
      win32api.RegSetValueEx(rkey, varname, 0, win32con.REG_SZ, value) 
      return True 
     except Exception, (error): 
      pass 
    finally: 
     win32api.RegCloseKey(rkey) 
    return False 

if len(sys.argv) == 3: 
    value = getenv_system(sys.argv[1]) 
    if value: 
     setenv_system(sys.argv[1],value + ";" + sys.argv[2]) 
     print "OK! %s = %s" % (sys.argv[1], getenv_system(sys.argv[1])) 
    else: 
     print "ERROR: No such environment variable. (%s)" % sys.argv[1] 
else: 
    print "Usage: appendenv.py envvar data_to_append" 
+1

Ist es freiwillig, dass das "get" das CurrentControlSet verwendet und dass das Set ControlSet001 verwendet? Wenn ja, könnten Sie erklären warum? – SuperOli

+0

@SuperOli, sie sind in fast allen Fällen gleich, aber Sie haben recht, es wäre sicherer CurrentControlSet in 'set' zu verwenden. Ich kann mich nicht erinnern, warum ich es damals so geschrieben habe. Ich werde die Antwort bearbeiten. (Weitere Informationen: http://support.microsoft.com/kb/100010) –

1

Diese link bietet eine Lösung, die die integrierte in winreg Bibliothek verwendet. nur

(copypasta)

import sys 
from subprocess import check_call 
if sys.hexversion > 0x03000000: 
    import winreg 
else: 
    import _winreg as winreg 

class Win32Environment: 
    """Utility class to get/set windows environment variable""" 

    def __init__(self, scope): 
     assert scope in ('user', 'system') 
     self.scope = scope 
     if scope == 'user': 
      self.root = winreg.HKEY_CURRENT_USER 
      self.subkey = 'Environment' 
     else: 
      self.root = winreg.HKEY_LOCAL_MACHINE 
      self.subkey = r'SYSTEM\CurrentControlSet\Control\Session Manager\Environment' 

    def getenv(self, name): 
     key = winreg.OpenKey(self.root, self.subkey, 0, winreg.KEY_READ) 
     try: 
      value, _ = winreg.QueryValueEx(key, name) 
     except WindowsError: 
      value = '' 
     return value 

    def setenv(self, name, value): 
     # Note: for 'system' scope, you must run this as Administrator 
     key = winreg.OpenKey(self.root, self.subkey, 0, winreg.KEY_ALL_ACCESS) 
     winreg.SetValueEx(key, name, 0, winreg.REG_EXPAND_SZ, value) 
     winreg.CloseKey(key) 
     # For some strange reason, calling SendMessage from the current process 
     # doesn't propagate environment changes at all. 
     # TODO: handle CalledProcessError (for assert) 
     check_call('''\ 
"%s" -c "import win32api, win32con; assert win32api.SendMessage(win32con.HWND_BROADCAST, win32con.WM_SETTINGCHANGE, 0, 'Environment')"''' % sys.executable) 
Verwandte Themen