【问题标题】:Set a persistent environment variable from cmd.exe从 cmd.exe 设置持久环境变量
【发布时间】:2011-08-19 09:07:56
【问题描述】:

我必须在不同的 Windows 机器上设置环境变量,但我不想通过进入“我的电脑”的属性屏幕来手动更改它们

我想使用批处理文件从命令行执行此操作。据我了解,使用 set 只会更改我将在命令窗口中调用的进程的变量。

我想肯定地设置它,所以以后在运行一个新进程时,它会使用我设置的那些新设置。有没有办法从命令行做到这一点?

【问题讨论】:

  • 如果它们是永久的,从命令行设置它们有什么意义?你不需要再做一次了。
  • 是的,但我必须在多台计算机上执行此操作,因此运行脚本会节省一些时间。
  • 好的,在这种情况下,您可以在一台计算机上设置您的环境并导出下面描述的条目并拥有一个 .reg 文件,如果您无法使用 SETX。
  • 这就是我所做的。谢谢。
  • RE: '从命令行设置它们有什么意义......' 在我工作的地方,为了测试/开发不同的值,需要不断要求将许多持久环境变量设置为不同的值软件的版本。许可意味着它不能以任何其他方式完成(例如运行 VM),因此我们唯一的办法是在批处理脚本中使用 SETX。使用 .reg 不太好,因为它更难记录/查看到底发生了什么

标签: windows batch-file environment-variables cmd


【解决方案1】:

使用SETX command(注意'x'后缀)设置在cmd窗口关闭后仍然存在的变量。

例如,设置一个值为“bar”的环境变量“foo”:

setx foo bar

尽管如果您打印使用 (setx /?) 时显示的“注释”值得阅读,尤其是:

2) 在本地系统上,此工具创建或修改的变量将在以后的命令窗口中可用,但在当前的 CMD.exe 命令窗口中不可用。

3) 在远程系统上,此工具创建或修改的变量将在下次登录会话时可用。

在 PowerShell 中,[Environment]::SetEnvironmentVariable 命令。

【讨论】:

  • SETX 似乎只在 windows XP SP2 上可用
  • 它适用于我的 Windows 7。您使用的是哪个版本的 Windows?
  • @jules:那么你可以从资源包中获得它。
  • 小心 SETX,它会将你的可变长度截断为 1024 个字符...在操作 %path% 时非常危险。
  • 使用 Power Shell 你可以[Environment]::SetEnvironmentVariable('PATH', "Whatever you need it to be", "Machine"),见msdn.microsoft.com/en-us/library/96xafkes(v=vs.110).aspx
【解决方案2】:

MSDN documentation for environment variables 告诉你该怎么做:

要以编程方式添加或修改系统环境变量,请将它们添加到 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment 注册表项,然后广播 WM_SETTINGCHANGE 消息lParam 设置为字符串“Environment”。这允许应用程序(例如 shell)获取您的更新。

您当然需要管理员权限才能执行此操作。我知道无法从 Windows 批处理中广播 Windows 消息,因此您需要编写一个小程序来执行此操作。

【讨论】:

  • 好的,考虑到您的解决方案,我创建了一个注册表 (.reg) 文件,其中包含我要添加/更改的环境变量。然后,我将在所有目标 PC 上运行此文件。我真的不需要发送 Windows 消息,因为我只需重新启动将受到影响的应用程序。谢谢。
  • 我在这里添加您的其他答案,因为这正是我偶然发现这个问题时所寻找的:stackoverflow.com/a/19705691/3543437
  • @David,那么为什么不在下面setx 呢?
  • 我认为这个 reg 的优点是不截断,不是 powershell
【解决方案3】:
:: Sets environment variables for both the current `cmd` window 
::   and/or other applications going forward.
:: I call this file keyz.cmd to be able to just type `keyz` at the prompt 
::   after changes because the word `keys` is already taken in Windows.

@echo off

:: set for the current window
set APCA_API_KEY_ID=key_id
set APCA_API_SECRET_KEY=secret_key
set APCA_API_BASE_URL=https://paper-api.alpaca.markets

:: setx also for other windows and processes going forward
setx APCA_API_KEY_ID     %APCA_API_KEY_ID%
setx APCA_API_SECRET_KEY %APCA_API_SECRET_KEY%
setx APCA_API_BASE_URL   %APCA_API_BASE_URL%

:: Displaying what was just set.
set apca

:: Or for copy/paste manually ...
:: setx APCA_API_KEY_ID     'key_id'
:: setx APCA_API_SECRET_KEY 'secret_key'
:: setx APCA_API_BASE_URL   'https://paper-api.alpaca.markets'

【讨论】:

  • 这极大地简化了我的算法工作效率并节省了很多时间
【解决方案4】:

确实 SET TEST_VARIABLE=value 仅适用于当前进程,因此需要 SETX。在用户级别永久存储环境变量的快速示例。

  1. 在 cmd 中,SETX TEST_VARIABLE etc 尚未应用(echo %TEST_VARIABLE% 显示 %TEST_VARIABLE%
  2. 快速查看:打开cmd,echo %TEST_VARIABLE%显示etc
  3. GUI 检查:系统属性 -> 高级 -> 环境变量 -> 用户变量 -> 您应该看到变量 TEST_VARIABLE 的值为 etc

【讨论】:

    【解决方案5】:

    VBScript (.vbs) 的示例

    Sub sety(wsh, action, typey, vary, value)
      Dim wu
      Set wu = wsh.Environment(typey)
      wui = wu.Item(vary)
      Select Case action
        Case "ls"
          WScript.Echo wui
        Case "del"
          On Error Resume Next
          wu.remove(vary)
          On Error Goto 0
        Case "set"
          wu.Item(vary) = value
        Case "add"
          If wui = "" Then
            wu.Item(vary) = value
          ElseIf InStr(UCase(";" & wui & ";"), UCase(";" & value & ";")) = 0 Then
            wu.Item(vary) = value & ";" & wui
          End If
        Case Else
          WScript.Echo "Bad action"
      End Select
    End Sub
    
    Dim wsh, args
    Set wsh = WScript.CreateObject("WScript.Shell")
    Set args = WScript.Arguments
    Select Case WScript.Arguments.Length
      Case 3
        value = ""
      Case 4
        value = args(3)
      Case Else
        WScript.Echo "Arguments - 0: ls,del,set,add; 1: user,system, 2: variable; 3: value"
        value = "```"
    End Select
    If Not value = "```" Then
      ' 0: ls,del,set,add; 1: user,system, 2: variable; 3: value
      sety wsh, args(0), args(1), UCase(args(2)), value
    End If
    

    【讨论】:

    • 您应该考虑在代码中添加一些上下文或解释。
    • 强大的代码+1。在没有setx 的情况下在 XP 上工作(并且无法安装它)。简单使用(以我为例):wsh.Environment("user").Item("myVar") = "my value"
    • 由于没有人费心,在XP上使用(不需要Resource Kit或setx),为所有(其他)DOS窗口完成{set foo = bar}:1.保存上面的代码as SetVar.vbs 2. setvar.vbs set system foo "bar" 注意,current DOS 窗口不会从中获取 FOO。发出 set foo=bar 来实现这一目标
    • 还要注意,这会在重新启动后继续存在(当您使用系统参数时)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-17
    • 1970-01-01
    • 2013-07-13
    • 2010-10-17
    相关资源
    最近更新 更多