WindowsコマンドラインからPATH変数を永久に更新する方法は?


122

set PATH=%PATH%;C:\\Something\\binコマンドライン(cmd.exe)から実行して実行すると、echo %PATH%この文字列がPATHに追加されます。コマンドラインを閉じて開くと、その新しい文字列はPATHにありません。

現在のプロセスだけでなく、将来のすべてのプロセスのコマンドラインからPATHを永続的に更新するにはどうすればよいですか?

システムのプロパティ→詳細→環境変数に移動し、そこでPATHを更新して、これを実行したくありません。

このコマンドは、Javaアプリケーションから実行する必要があります(他の質問を参照してください)。


5
powershellを使用すると、かなり単純なstackoverflow.com/questions/714877/…になります。cmdを使用すると、わかりません。レジストリを変更するか、.netアセンブリを何らかの方法でプルする必要がある場合があります。
オースティンホームズ

1
言ったように、私はこれをJavaアプリケーション内から行わなければなりません。Javaを使用していくつかのcmdコマンドを実行するだけだと思ったRuntime.getRuntime().exec("my command");
vale4674

回答:


43

これを行う方法に関するドキュメントは、MSDNにあります。重要な抜粋はこれです:

プログラムでシステム環境変数を追加または変更するには、それらをHKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Control \ Session Manager \ Environmentレジストリキーに追加してから、WM_SETTINGCHANGElParamが文字列 "Environment"に設定されたメッセージをブロードキャストします。これにより、シェルなどのアプリケーションが更新を取得できます。

このキーを変更できるようにするには、アプリケーションに管理者権限の昇格が必要になることに注意してください。

コメントごとに、ユーザーごとの環境のみを変更してもよいことを示します。これを行うには、HKEY_CURRENT_USER \ Environmentの値を編​​集します。以前と同様に、WM_SETTINGCHANGEメッセージをブロードキャストすることを確認してください。

JNIレジストリクラスを使用すると、Javaアプリケーションからこれを簡単に行うことができます。


1
はい、JNIレジストリクラスを使用します。より大きな問題は、アプリがおそらく昇格されて実行されないことです。あなたはそれをそれを行う方法を知っていますか?アプリのごく一部のみを昇格させたい場合(つまり、この変更を行う場合)、最も簡単な解決策は、ジョブを実行する非常にシンプルなC ++アプリであり、アプリマニフェストでマークを付けて、別のプロセスとして実行します。 UACダイアログを起動します。
デビッド

1
HKEY_CURRENT_USER\Environment標高の要件を回避するために編集することもできます。
kichik

@David Heffernanはい、これだけが昇格する必要があります。だからあなたの提案はC ++アプリケーションを書いて私のJavaアプリケーションからそれを実行することですか?これを行う方法のコード例またはリンクを教えていただけますか?
vale4674

うん。デビッドが言ったように。あなただけが標高を上げません。これにより、現在のユーザーのみの環境が変更されることにも言及する必要があります。
kichik

これを個別のプロセスに分離して、システムPATHを変更するときにUACダイアログのみを強制する必要があります。レジストリの読み取りと書き込みをいくつか行い、SendMessageが続く単純なC ++アプリが必要です。設定するrequestedExecutionLevelにはrequireAdministrator、アプリのマニフェストインチ
デビッドヘ

145

以下を使用できます。

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

ただし、setx格納された文字列を1024バイトに切り捨て、PATHを破損させる可能性があります。

/M変更されるPATHHKEY_LOCAL_MACHINEはなく、HKEY_CURRENT_USER。つまり、ユーザー変数ではなくシステム変数です。例えば:

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

新しいPATHは現在のには表示されないことに注意してくださいcmd.exe

しかし、レジストリまたは新しいものcmd.exe"set p"見ると、新しい値がわかります。


2
setxユーザーのパスではなく、マシンのパスを変更する方法はありますか?
Corey Ogburn 2013年

4
ここから、現在ログインしているユーザーだけでなく、/mWindows XPおよび7でコマンドの最後に使用するマシンの変数を設定できる可能性があることがわかります。私はまだ試していません。
パニー

1
setxコマンドの実行時にエラーが発生しました「デフォルトのオプションは '2'時間以上は許可されていません」どうすればバイパスできますか?
Nam G VU

12
@KilgoreCodのコメント:コマンドの使用に注意:最近の多くの(ほとんど?)インストールでは、PATH変数が長くなる-setxは格納された文字列を1024バイトに切り捨て、PATHを破損させる可能性がありますsuperuser.com/の説明を参照)q / 812754)。
beresfordt 2015年

2
すでに1200バイトを超えているパスをエコー出力してみます。setxの代わりに他の方法?
lawphotog 2018年

37

コマンドを使用しないように注意します

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

その実装の「機能」のためにPATH変数を変更します。最近の多くの(ほとんど?)インストールでは、変数が長くsetxなり、格納された文字列が1024バイトに切り捨てられ、PATHが破損する可能性があります(こちらの説明を参照)。

私は特にこの問題を報告するためにサインアップしたため、5月2日に投稿された回答に直接コメントするサイトの評判に欠けています。そのようなコメントを追加してくれたberesfordtに感謝します


9

このPythonスクリプト[*]はまさに次のことを行います。

"""
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:])

以下はsetenv.py、現在のパスのどこかにあるファイルに保存されている場合の使用例です。これらの例では、私は管理者権限を持っていなかったので、変更はローカルユーザーのレジストリツリーにのみ影響することに注意してください。

> 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/


4

参考のために、コードを介してパスを変更する方法を検索する人のために、私はこのWebページからDelphiプログラマーによる有用な投稿を引用しています:http : //www.tek-tips.com/viewthread.cfm?qid=686382

TonHu(プログラマー)22 Oct 03 17:57元の投稿を読んだところが見つかりました。ここにあります:http : //news.jrsoftware.org/news/innosetup.isx/msg02129 ....

あなたが必要とするものの抜粋はこれです:

LParamで文字列「Environment」を指定する必要があります。Delphiでは、次のようにします。

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

これは、(ao)InnoSetupの作者であるJordan Russell(http://www.jrsoftware.org)によって提案されました(「Inno SetupはWindowsプログラムの無料インストーラーです。機能セットと安定性の商用インストーラー。」)(もっと多くの人にInnoSetupを使用してほしい)

HTH


レジストリを変更する必要があります。また、整数へのキャストは貧弱です。代わりに、64ビット互換性のためにLPARAMにキャストしてください。
David Heffernan 2015


4

ユーザーがアクセスが制限されていてポータブルアプリを使用している企業ネットワークでは、次のコマンドライントリックがあります。

  1. ユーザー環境変数を照会しますreg query "HKEY_CURRENT_USER\Environment""HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"LOCAL_MACHINEに使用します。
  2. 新しいユーザー環境変数を追加:reg add "HKEY_CURRENT_USER\Environment" /v shared_dir /d "c:\shared" /t REG_SZREG_EXPAND_SZ他の%%変数を含むパスに使用します。
  3. 既存の環境変数を削除します:reg delete "HKEY_CURRENT_USER\Environment" /v shared_dir

3

このスクリプト http://www.autohotkey.com/board/topic/63210-modify-system-path-gui/

には、必要に応じてリファクタリングできる必要なすべてのWindows API呼び出しが含まれています。実際には、システムパスを簡単に変更するためのAutoHotkey GUIです。管理者として実行する必要があります。


質問を読んでください。再び。
jiggunjer

素晴らしいスクリプト。HotKeyを使用していますが、スクリプトを追加する方法や方法がわかりません。ヘルプを提供したり、リンクを提供したり、実行する必要があることを説明したりできますか?
jwzumwalt
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.