PATH değişkeni Windows komut satırından kalıcı olarak nasıl güncellenir?


122

Ben yürütmek Eğer set PATH=%PATH%;C:\\Something\\binkomut satırından ( cmd.exe) ve daha sonra yürütmek echo %PATH%ben PATH eklendi Bu dize görüyoruz. Komut satırını kapatıp açarsam, bu yeni dize PATH'de olmaz.

PATH'i yalnızca mevcut işlem için değil, gelecekteki tüm işlemler için komut satırından kalıcı olarak nasıl güncelleyebilirim?

Bunu Sistem Özellikleri → Gelişmiş → Ortam değişkenlerine gidip PATH'i orada güncelleyerek yapmak istemiyorum.

Bu komut bir Java uygulamasından çalıştırılmalıdır (lütfen diğer soruma bakın ).


5
Powershell'i kullanmak oldukça basittir stackoverflow.com/questions/714877/… . Cmd kullanarak emin değilim. Kayıt defterini değiştirmeniz veya bir şekilde .net derlemesini çekmeniz gerekebilir.
Austen Holmes

1
Dediğim gibi, bunu java uygulamasının içinden yapmam gerekiyor. Sadece useng java'nın bazı cmd komutlarını çalıştırmayı düşündümRuntime.getRuntime().exec("my command");
vale4674

Yanıtlar:


43

Bunun nasıl yapılacağına ilişkin belgeler MSDN'de bulunabilir . Anahtar alıntı şudur:

Sistem ortam değişkenlerini programlı olarak eklemek veya değiştirmek için, bunları HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Control \ Session Manager \ Environment kayıt defteri anahtarına ekleyin , ardından WM_SETTINGCHANGElParam "Environment" dizesine ayarlanmış bir mesaj yayınlayın . Bu, kabuk gibi uygulamaların güncellemelerinizi almasına izin verir.

Bu anahtarı değiştirebilmek için uygulamanızın yükseltilmiş yönetici haklarına ihtiyaç duyacağını unutmayın.

Yorumlarda, yalnızca kullanıcı başına ortamı değiştirmekten memnun olacağınızı belirtirsiniz. Bunu, HKEY_CURRENT_USER \ Environment içindeki değerleri düzenleyerek yapın . Daha önce olduğu gibi, bir WM_SETTINGCHANGEmesaj yayınladığınızdan emin olun .

Bunu Java uygulamanızdan JNI kayıt sınıflarını kullanarak yeterince kolay bir şekilde yapabilmelisiniz.


1
Evet, JNI kayıt sınıflarını kullanarak. Daha büyük bir sorun, uygulamanızın muhtemelen yüksek çalışmamasıdır. Bunu nasıl yapacağını biliyor musun? Uygulamanızın yalnızca küçük bir bölümünün yükseltilmiş olarak çalışmasını istiyorsanız (yani, yalnızca bu değişikliği yapmak için), o zaman en basit çözüm, işi yapmak için çok basit bir C ++ uygulamasıdır, uygulama bildirimi ile işaretlenir ve ardından ayrı bir işlem olarak yürütülür. UAC diyaloğunu kışkırtır.
David Heffernan

1
HKEY_CURRENT_USER\EnvironmentYükseklik gereksinimini önlemek için de düzenleme yapabilirsiniz .
kichik

@David Heffernan Evet sadece bu şey yükseltilmiş çalışmalı. Yani öneriniz C ++ uygulaması yazıp java uygulamamdan çalıştırmak mı? Bunun nasıl yapılacağına dair bana örnek bir kod veya bağlantı verebilir misiniz?
vale4674

Evet. Tıpkı David'in dediği gibi. Sadece sen yükselmiyorsun. Bunun sadece mevcut kullanıcı için ortamı değiştireceğini de belirtmeliyim.
kichik

Bunu ayrı bir sürece ayırmanız gerekir, böylece sistem PATH'sini değiştirirken yalnızca bir UAC iletişim kutusu zorlarsınız. Sadece birkaç kayıt okuma ve yazma ve ardından bir SendMessage içeren basit bir C ++ uygulamasına ihtiyaç duyar. Set requestedExecutionLeveliçin requireAdministratoruygulama manifestinde.
David Heffernan

145

Kullanabilirsiniz:

setx PATH "%PATH%;C:\\Something\\bin"

Ancak, setxsaklanan dizeyi 1024 bayta keserek potansiyel olarak PATH'i bozacaktır.

/Mdeğişecek PATHiçinde HKEY_LOCAL_MACHINEyerine HKEY_CURRENT_USER. Başka bir deyişle, kullanıcının yerine bir sistem değişkeni. Örneğin:

SETX /M PATH "%PATH%;C:\your path with spaces"

Unutmayın, yeni PATH mevcut yolunuzda görünmez cmd.exe.

Eğer kayıt defterinde veya yeni bakmak Ama eğer cmd.exebirlikte "set p"size yeni değeri görebilirsiniz.


2
Kullanmak için bir yolu var mı setxkullanıcının yol yerine makinenin yolunu değiştirmek için?
Corey Ogburn

4
Gönderen burada bunu kullanarak anda oturum açan için değil, makine için sadece bir değişken ayarlamak mümkün olabileceğini söyleyebilir /mBen olsa denemedim Windows XP üzerinde, komutun sonunda ve 7..
panny

1
setx"Varsayılan seçeneğe '2' süreden fazla izin verilmiyor" komutunu çalıştırırken hata aldım Nasıl atlanır?
Nam G VU

12
@KilgoreCod yorumlar: Ben komutunu kullanarak karşı uyarıyoruz: Bu günlerde birçok (? Çoğu) kurulumlarında YOL değişkeni uzun olacak - setx potansiyel PATH bozulmasını, 1024 bayt depolanan dizeyi kesmek olacaktır (burada tartışmaya bakınız superuser.com/ q / 812754 ).
beresfordt

2
Zaten 1200 bayttan fazla olan yolu yankılamaya çalışıyorum. setx yerine başka bir yol var mı?
lawphotog

37

Komutu kullanmamaya dikkat ediyorum

setx PATH "%PATH%;C:\Something\bin"

PATH değişkenini, uygulamasının bir "özelliği" nedeniyle değiştirmek için. Birçok (? Çoğu) kurulumlarında bugünlerde değişken uzun olacak - setxpotansiyel olarak PATH (tartışma bozulmasını, 1024 bayt depolanan dizeyi kesmek olacaktır burada ).

( Bu sorunu işaretlemek için özel olarak kaydoldum ve bu nedenle, 2 Mayıs 2012'de yayınlanan yanıta doğrudan yorum yapacak site saygınlığım yok. Böyle bir yorum eklediği için beresfordt'a teşekkür ederim )


9

Bu Python betiği [*] tam olarak şunu yapar:

"""
Show/Modify/Append registry env-vars (ie `PATH`) and notify Windows-applications to pickup changes.

First attempts to show/modify HKEY_LOCAL_MACHINE (all users), and 
if not accessible due to admin-rights missing, fails-back 
to HKEY_CURRENT_USER.
Write and Delete operations do not proceed to user-tree if all-users succeed.

Syntax: 
    {prog}                  : Print all env-vars. 
    {prog}  VARNAME         : Print value for VARNAME. 
    {prog}  VARNAME   VALUE : Set VALUE for VARNAME. 
    {prog}  +VARNAME  VALUE : Append VALUE in VARNAME delimeted with ';' (i.e. used for `PATH`). 
    {prog}  -VARNAME        : Delete env-var value. 

Note that the current command-window will not be affected, 
changes would apply only for new command-windows.
"""

import winreg
import os, sys, win32gui, win32con

def reg_key(tree, path, varname):
    return '%s\%s:%s' % (tree, path, varname) 

def reg_entry(tree, path, varname, value):
    return '%s=%s' % (reg_key(tree, path, varname), value)

def query_value(key, varname):
    value, type_id = winreg.QueryValueEx(key, varname)
    return value

def yield_all_entries(tree, path, key):
    i = 0
    while True:
        try:
            n,v,t = winreg.EnumValue(key, i)
            yield reg_entry(tree, path, n, v)
            i += 1
        except OSError:
            break ## Expected, this is how iteration ends.

def notify_windows(action, tree, path, varname, value):
    win32gui.SendMessage(win32con.HWND_BROADCAST, win32con.WM_SETTINGCHANGE, 0, 'Environment')
    print("---%s %s" % (action, reg_entry(tree, path, varname, value)), file=sys.stderr)

def manage_registry_env_vars(varname=None, value=None):
    reg_keys = [
        ('HKEY_LOCAL_MACHINE', r'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'),
        ('HKEY_CURRENT_USER', r'Environment'),
    ]
    for (tree_name, path) in reg_keys:
        tree = eval('winreg.%s'%tree_name)
        try:
            with winreg.ConnectRegistry(None, tree) as reg:
                with winreg.OpenKey(reg, path, 0, winreg.KEY_ALL_ACCESS) as key:
                    if not varname:
                        for regent in yield_all_entries(tree_name, path, key):
                            print(regent)
                    else:
                        if not value:
                            if varname.startswith('-'):
                                varname = varname[1:]
                                value = query_value(key, varname)
                                winreg.DeleteValue(key, varname)
                                notify_windows("Deleted", tree_name, path, varname, value)
                                break  ## Don't propagate into user-tree.
                            else:
                                value = query_value(key, varname)
                                print(reg_entry(tree_name, path, varname, value))
                        else:
                            if varname.startswith('+'):
                                varname = varname[1:]
                                value = query_value(key, varname) + ';' + value
                            winreg.SetValueEx(key, varname, 0, winreg.REG_EXPAND_SZ, value)
                            notify_windows("Updated", tree_name, path, varname, value)
                            break  ## Don't propagate into user-tree.
        except PermissionError as ex:
            print("!!!Cannot access %s due to: %s" % 
                    (reg_key(tree_name, path, varname), ex), file=sys.stderr)
        except FileNotFoundError as ex:
            print("!!!Cannot find %s due to: %s" % 
                    (reg_key(tree_name, path, varname), ex), file=sys.stderr)

if __name__=='__main__':
    args = sys.argv
    argc = len(args)
    if argc > 3:
        print(__doc__.format(prog=args[0]), file=sys.stderr)
        sys.exit()

    manage_registry_env_vars(*args[1:])

Aşağıda, mevcut yolunuzda bir setenv.pyyere denilen bir dosyaya kaydedildiğini varsayarak bazı kullanım örnekleri verilmiştir . Bu örneklerde yönetici haklarına sahip olmadığım için değişikliklerin yalnızca yerel kullanıcımın kayıt defteri ağacını etkilediğini unutmayın:

> REM ## Print all env-vars
> setenv.py
!!!Cannot access HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session   Manager\Environment:PATH due to: [WinError 5] Access is denied
HKEY_CURRENT_USER\Environment:PATH=...
...

> REM ## Query env-var:
> setenv.py PATH C:\foo
!!!Cannot access HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session   Manager\Environment:PATH due to: [WinError 5] Access is denied
!!!Cannot find HKEY_CURRENT_USER\Environment:PATH due to: [WinError 2] The system cannot find the file specified

> REM ## Set env-var:
> setenv.py PATH C:\foo
!!!Cannot access HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session   Manager\Environment:PATH due to: [WinError 5] Access is denied
---Set HKEY_CURRENT_USER\Environment:PATH=C:\foo

> REM ## Append env-var:
> setenv.py +PATH D:\Bar
!!!Cannot access HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session   Manager\Environment:PATH due to: [WinError 5] Access is denied
---Set HKEY_CURRENT_USER\Environment:PATH=C:\foo;D:\Bar

> REM ## Delete env-var:
> setenv.py -PATH
!!!Cannot access HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session   Manager\Environment:PATH due to: [WinError 5] Access is denied
---Deleted HKEY_CURRENT_USER\Environment:PATH

[*] Http://code.activestate.com/recipes/416087-persistent-environment-variables-on-windows/ adresinden uyarlanmıştır.


4

Referans amacıyla, kod aracılığıyla yolu nasıl değiştireceğini arayan herkes için, bu web sayfasından bir Delphi programcısının yararlı bir gönderisinden alıntı yapıyorum: http://www.tek-tips.com/viewthread.cfm?qid=686382

TonHu (Programcı) 22 Eki 03 17:57 Orijinal gönderiyi okuduğum yerde buldum, burada: http://news.jrsoftware.org/news/innosetup.isx/msg02129 ....

İhtiyacınız olan şeyin alıntısı şudur:

LParam'da "Ortam" dizesini belirtmelisiniz. Delphi'de bunu şu şekilde yaparsınız:

 SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, Integer(PChar('Environment')));

(Ao) InnoSetup'ın yazarı Jordan Russell, http://www.jrsoftware.org tarafından önerilmiştir ("Inno Setup, Windows programları için ücretsiz bir yükleyicidir. İlk olarak 1997'de piyasaya sürülen Inno Setup, bugün rakip ve hatta birçok özellik kümesinde ve kararlılıkta ticari yükleyiciler. ") (InnoSetup'ı daha fazla kişinin kullanmasını istiyorum)

HTH


Kayıt defterini değiştirmeniz gerekir. Ayrıca, Tamsayıya dönüştürme zayıftır. 64 bit uyumluluğu için bunun yerine LPARAM'a yayınlayın.
David Heffernan


4

Kullanıcının yalnızca sınırlı erişime sahip olduğu ve taşınabilir uygulamaları kullandığı bir şirket ağında şu komut satırı püf noktaları vardır:

  1. Kullanıcı env değişkenleri sorgula: reg query "HKEY_CURRENT_USER\Environment". "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"LOCAL_MACHINE için kullanın .
  2. Yeni kullanıcı env değişkeni ekleyin: reg add "HKEY_CURRENT_USER\Environment" /v shared_dir /d "c:\shared" /t REG_SZ. REG_EXPAND_SZDiğer %% değişkenlerini içeren yollar için kullanın .
  3. Varolan env değişkeni silin: reg delete "HKEY_CURRENT_USER\Environment" /v shared_dir.

3

Bu komut dosyası http://www.autohotkey.com/board/topic/63210-modify-system-path-gui/

ihtiyaçlarınız için yeniden düzenlenebilen tüm gerekli Windows API çağrılarını içerir. Aslında, Sistem YOLUNU kolayca değiştirmek için bir AutoHotkey GUI'dir. Yönetici olarak çalıştırılması gerekir.


Soruyu okuyun. Tekrar.
jiggunjer

Harika senaryo. HotKey kullanıyorum ancak komut dosyasını eklemek için nasıl veya ne yapmam gerektiğini bilmiyorum. Yardım önerebilir, bir bağlantı sunabilir veya ne yapılması gerektiğini açıklayabilir misiniz?
jwzumwalt
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.