2009-01-28 45 views
7

Theo sau từ previous question của tôi, có thể tạo một tập lệnh Python liên tục thay đổi biến môi trường Windows không?Tập lệnh python có thể liên tục thay đổi biến môi trường Windows không? (thanh lịch)

Thay đổi đối với os.environ không tồn tại khi trình thông dịch python chấm dứt. Nếu tôi đã viết kịch bản này trên UNIX, tôi có thể thực hiện một số việc như:

set foo=`myscript.py` 

Nhưng alas, cmd.exe không có bất kỳ thứ gì hoạt động giống như hành vi đánh dấu ngược của sh. Tôi đã thấy một giải pháp rất dài dòng ... nó 'aint đẹp, vì vậy chắc chắn chúng ta có thể cải thiện về điều này:

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

Chắc chắn tâm trí tại Microsoft có một giải pháp tốt hơn thế này!

Lưu ý: trùng lặp chính xác this question.

+0

Tôi không nghĩ rằng câu hỏi là một bản sao chính xác kể từ khi câu hỏi của tôi là có liên quan với chỉ dành cho Windows. –

Trả lời

1

Giải pháp dài hơi của bạn có lẽ là ý tưởng tốt nhất; Tôi không tin rằng điều này là có thể từ Python trực tiếp. Bài viết này cho thấy một cách khác, sử dụng một tập tin thực thi tạm thời:

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

+5

Điều đó không làm thay đổi môi trường liên tục. Nó chỉ thay đổi một bản sao của các biến môi trường. – ralphtheninja

+0

Đó là những gì tôi muốn! –

+2

@ Salim Fadhley Nếu đó là những gì bạn muốn, tại sao bạn yêu cầu một cái gì đó khác nhau trong câu hỏi của bạn? Bằng cách chấp nhận câu trả lời không trả lời câu hỏi bạn lừa dối những người đang tìm kiếm thông tin ... –

5

Bạn có thể muốn thử Python Win32 Extensions, được phát triển bởi Mark Hammond, được bao gồm trong ActivePython (hoặc có thể được cài đặt riêng). Bạn có thể tìm hiểu cách thực hiện nhiều tác vụ liên quan đến Windows trong Hammond's and Robinson's book.

Sử dụng PyWin32 để truy cập cửa sổ COM đối tượng, một chương trình Python có thể sử dụng Environment Property của đối tượng WScript.Shell - một tập hợp các biến môi trường.

3

Windows đặt Biến môi trường từ các giá trị được lưu trữ trong Registry cho từng quy trình độc lập.

Tuy nhiên, có một công cụ trong Windows XP Service Pack 2 Support Tools có tên setx.exe cho phép bạn thay đổi biến môi trường toàn cục từ dòng lệnh.

+4

setx.exe cũng được cài đặt với Vista. Tuy nhiên, tôi có ấn tượng rằng áp phích ban đầu thực sự muốn tìm hiểu cách sửa đổi môi trường của quy trình cha mẹ, không làm cho các giá trị biến môi trường tồn tại trong quá trình khởi động lại. – bk1e

3

Giải pháp của tôi sử dụng 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

Có tự nguyện rằng "get" sử dụng CurrentControlSet và tập hợp sử dụng ControlSet001 không? Nếu vậy, bạn có thể giải thích tại sao? – SuperOli

+0

@ SuperOli, chúng bằng nhau trong hầu hết các trường hợp, nhưng bạn nói đúng là sẽ an toàn hơn khi sử dụng CurrentControlSet trong 'set'. Tôi không nhớ tại sao tôi lại viết như thế. Sẽ chỉnh sửa câu trả lời. (Thông tin thêm: http://support.microsoft.com/kb/100010) –

1

link này cung cấp một giải pháp mà sử dụng được xây dựng trong winreg thư viện.

(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) 
Các vấn đề liên quan