【问题标题】:Command line to remove an environment variable from the OS level configuration从操作系统级别配置中删除环境变量的命令行
【发布时间】:2012-10-24 17:38:20
【问题描述】:

Windows 有setx 命令:

Description:
    Creates or modifies environment variables in the user or system
    environment.

所以你可以像这样设置一个变量:

setx FOOBAR 1

你可以像这样清除值:

setx FOOBAR ""

但是,变量并没有被删除。它保留在注册表中:

那么你将如何实际删除变量?

【问题讨论】:

标签: windows registry environment-variables


【解决方案1】:

要从当前环境中删除变量(不是永久):

set FOOBAR=

要从 user 环境中永久删除变量(这是setx 放置它的默认位置):

REG delete HKCU\Environment /F /V FOOBAR

如果变量是在 system 环境中设置的(例如,如果您最初使用 setx /M 设置它),则以管理员身份运行:

REG delete "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /F /V FOOBAR

注意:上面的REG 命令不会影响任何现有进程(以及从现有进程派生的一些新进程),因此如果更改立即生效很重要,那么最简单和最可靠的做法是是注销并重新登录或重新启动。如果这不是一个选项,或者您想更深入地挖掘,这里的一些其他答案有一些可能适合您的用例的好建议。

【讨论】:

  • 这个解决方案似乎不起作用 - 或者我误解了一些基本的东西。我做setx JUNK Hello。打开新的cmd。键入 echo %JUNK% 并获取 Hello。然后我执行REG delete "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /F /V JUNK,并确认该值已从注册表中消失。我打开新的 cmd 并输入echo %JUNK%,仍然得到Hello。搜索注册表显示不存在“垃圾”。请不要告诉我您需要重新启动!
  • 感谢您的回复。我正在从“开始”菜单打开一个新的命令窗口。我已经尝试了该命令的两个版本。事实上,我第一次输入user环境命令的时候,就成功了。然后,当我重新输入命令时,我得到The system was unable to find the specified registry or key value。此外,使用regedit 在注册表中对JUNK 进行全局搜索没有任何结果。尽管如此,当我打开一个新的命令窗口(通过开始/附件,或运行中的 cmd.exe)并输入 echo %JUNK% 时,该值仍然存在!
  • 啊!您认为这样做的合理性是什么?我总是尽可能避免管理员 - UNIX/BSD/Linux 教育。感谢一百万令人敬畏的勤奋。 +1
  • 可能只是语义上的,但删除(从注册表中)会立即生效。在您再次登录之前,不会从注册表重新初始化环境。您可以结合 2 个命令将其从当前环境中删除(这会将其从下一个 cmd shell 的 SET 列表中删除),然后将其从注册表中删除,例如:SETX FOOBAR "" & REG delete HKCU\Environment /F /V FOOBAR
  • 不重新启动环境似乎没有更新的原因是因为 explorer.exe 不知道它已被更新。请参阅我的答案以获得完整的解释和解决方案。
【解决方案2】:

要从当前命令会话中删除变量而不永久删除它,请使用常规的内置 set 命令 - 只需在等号后不添加任何内容:

set FOOBAR=

要确认,请运行不带参数的set 并检查当前环境。该变量应该完全从列表中丢失。

注意:这只会从当前环境中删除变量 - 它不会将更改保存到注册表。当一个新的命令进程启动时,变量将返回。

【讨论】:

  • 这绝对不是答案,我发现有这么多赞成票令人不安。这仅对当前命令会话有效。启动一个新的命令窗口,var 又回来了。
  • @joescii 你觉得这很奇怪吗?这回答了问题标题中的问题。所以显然问题标题需要更具体。
  • @oberlies 我不同意它回答了标题中的问题,因为这在操作系统级别不起作用,而仅在当前命令窗口中起作用。其次,您的观点表明问题的细节部分无关紧要。
  • @oberlies 不幸的是,编辑似乎没有成功——它仍然得到了支持。我想即使它没有回答实际问题,人们也会觉得它很有用,在这种情况下,它可能值得投票(是吗?)。至少它没有被标记为接受,这会产生误导。
  • 我应该评论一下我投反对票的原因。显然因为这只适用于当前会话。
【解决方案3】:

这已经涉及了很多,但是缺少一条重要的信息。希望我能帮助弄清楚这是如何工作的,并为疲惫的旅行者提供一些缓解。 :-)

从当前进程中删除

显然,每个人都知道你这样做只是为了从当前进程中删除一个环境变量:

set FOO=

永久删除

有两组环境变量,系统范围的和用户的。

删除用户环境变量:

reg delete "HKCU\Environment" /v FOO /f

删除系统范围的环境变量:

REG delete "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /F /V FOO

无需重启即可应用价值

这是缺少的魔法信息!您想知道为什么在执行此操作后,当您启动一个新的命令窗口时,环境变量仍然存在。原因是 explorer.exe 没有更新其环境。当一个进程启动另一个进程时,新进程会从启动它的进程继承环境。

有两种方法可以在不重新启动的情况下解决此问题。最暴力的方法是杀死你的 explorer.exe 进程并重新启动它。您可以通过Task Manager 执行此操作。但是,我不推荐这种方法。

另一种方法是告诉 explorer.exe 环境已经改变,它应该重新读取它。这是通过广播 Windows 消息 (WM_SETTINGCHANGE) 来完成的。这可以通过一个简单的 PowerShell 脚本来完成。您可以轻松编写一个来执行此操作,但我在 Update Window Settings After Scripted Changes 中找到了一个:

if (-not ("win32.nativemethods" -as [type])) {
    add-type -Namespace Win32 -Name NativeMethods -MemberDefinition @"
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern IntPtr SendMessageTimeout(
            IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam,
            uint fuFlags, uint uTimeout, out UIntPtr lpdwResult);
        "@
}

$HWND_BROADCAST = [intptr]0xffff;
$WM_SETTINGCHANGE = 0x1a;
$result = [uintptr]::zero

[win32.nativemethods]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE,[uintptr]::Zero, "Environment", 2, 5000, [ref]$result);

总结

因此,要删除名为“FOO”的用户环境变量并将更改反映在您之后启动的进程中,请执行以下操作。

  1. 将 PowerShell 脚本保存到文件中(我们将其命名为 updateenv.ps1)。
  2. 从命令行执行此操作:reg delete "HKCU\Environment" /v FOO /f
  3. 运行 updateenv.ps1。
  4. 关闭并重新打开命令提示符,您会看到不再定义环境变量。

请注意,您可能需要更新 PowerShell 设置以允许您运行此脚本,但我将把它作为 Google-fu 练习留给您。强>

【讨论】:

  • 您有什么特别的原因不建议您杀死并重新启动资源管理器吗?我一直这样做。
  • 嗯,首先想到的是两个。首先是强制终止进程会导致内存泄漏。是的,进程应该是沙箱,但即使是 Windows 任务管理器也会警告您不要轻易这样做。另一个更个人的原因是我的强迫症。当您杀死并重新启动资源管理器时,任务栏中的所有图标(包括单击一个图标时的重复图标)都会重新排列。我喜欢我的图标按照我打开东西的顺序排列。
  • 哇。我一直在寻找的魔法命令就像 Windows 中的source .bashrc(或其表亲)一样。这对我来说是“参考这个”行的顶部。
【解决方案4】:

PowerShell 中,您可以使用 .NET [System.Environment]::SetEnvironmentVariable() 方法:

  • 删除一个名为FOO用户环境变量

    [Environment]::SetEnvironmentVariable('FOO', $null, 'User')
    

请注意,$null 用于更好地表示删除变量的意图,尽管在技术上它实际上与在这种情况下传递'' 相同。

  • 删除名为FOO系统(机器级)环境变量 - 需要提升(必须以管理员身份运行):

    [Environment]::SetEnvironmentVariable('FOO', $null, 'Machine')
    

除了执行速度更快之外,与reg.exe-based method 相比的优势在于其他应用程序会通过WM_SETTINGCHANGE 消息收到更改通知(尽管并非所有应用程序都会监听该消息)。

【讨论】:

  • 这是最好的答案。
  • 此方法无需重启。多么优雅的解决方案!
【解决方案5】:

我同意with CupawnTae

SET 对更改主环境没有用处。

仅供参考:系统变量在HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment 中(比用户变量长很多)。

因此,名为 FOOBAR 的系统变量的完整命令是:

REG delete "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /F /V FOOBAR

(注意处理空格所需的引号。)

setx 命令不支持删除语法太糟糕了。 :(

PS:负责任地使用 - 如果你杀死了你的路径变量,不要怪我!

【讨论】:

  • @CMCDragonkai 在原始问题中明确提到 - 它不会删除注册表项,它只是将其空白。实际问题是如何从注册表中删除它
  • 我只是补充一下,您可能需要重新启动/刷新 cmd 才能生效。
  • @jiggunjer,如何刷新?
  • @Pacerier 只需打开一个新终端。
【解决方案6】:

删除而不重新启动

OP 的问题确实得到了广泛的回答,包括如何避免通过 powershell、vbscript 或你的名字重新启动。

但是,如果您只需要坚持使用 cmd 命令并且没有能够调用 powershell 或 vbscript 的奢侈,您可以使用以下方法:

rem remove from current cmd instance
  SET FOOBAR=
rem remove from the registry if it's a user variable
  REG delete HKCU\Environment /F /V FOOBAR
rem remove from the registry if it's a system variable
  REG delete "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /F /V FOOBAR
rem tell Explorer.exe to reload the environment from the registry
  SETX DUMMY ""
rem remove the dummy
  REG delete HKCU\Environment /F /V DUMMY

所以这里的神奇之处在于,通过使用“setx”将某些内容分配给您不需要的变量(在我的示例中为 DUMMY),您可以强制 Explorer.exe 从注册表中重新读取变量,而无需 powershell。然后你清理那个假人,即使那个人会在 Explorer 的环境中停留一段时间,它也可能不会伤害任何人。

或者,如果在删除变量后您需要设置新变量,那么您甚至不需要任何虚拟变量。只需使用 SETX 设置新变量,就会自动清除您刚刚从任何可能开始的新 cmd 任务中删除的变量。

背景信息:我刚刚通过修改现有的 cmd 脚本,成功地使用这种方法在我工作的所有计算机上用同名的系统变量替换了一组用户变量。手动操作的计算机太多,将额外的 powershell 或 vbscript 复制到所有计算机也不实际。我迫切需要用系统变量替换用户的原因是用户变量在漫游配置文件中得到同步(没有考虑到这一点),所以使用相同的 Windows 登录但需要不同值的多台机器混淆了。

【讨论】:

  • 这是一个聪明的答案。
【解决方案7】:

DougWare's answer 中的命令不起作用,但它起作用了:

reg delete "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v FOOBAR /f

快捷方式HKLM可用于HKEY_LOCAL_MACHINE

【讨论】:

  • 另外,用户环境变量在“HKCU\Environment”下
  • @Tzrlk,不匹配的原因是什么?为什么它不在 HKLM\Environment 那里?
  • @Pacerier:我不知道他们为什么将它们放在如此完全不同的位置,但是如果您想确保您已删除系统或/和用户变量中的一个/两个,它有助于知道他们在完全不同的地方。
  • @Tzrlk,一定又是 Windows 端的一些搞砸的设计。
【解决方案8】:
setx FOOBAR ""

只是导致 FOOBAR 的值为空字符串。 (虽然,它使用带有“”的set 命令显示,所以双引号可能是字符串。)

我用过:

set FOOBAR=

然后 FOOBAR 不再列在 set 命令中。 (不需要注销。)

Windows 7 32 位,使用命令提示符,非管理员是我使用的。 (不是 cmd 或 Windows + R,可能不同。)

顺便说一句,我创建后在注册表中的任何位置都没有看到我创建的变量。我使用RegEdit 不是管理员。

【讨论】:

    【解决方案9】:

    您还可以创建一个小的VBScript 脚本:

    Set env = CreateObject("WScript.Shell").Environment("System")
    If env(WScript.Arguments(0)) <> vbNullString Then env.Remove WScript.Arguments(0)
    

    然后将其称为%windir%\System32\cscript.exe //Nologo "script_name.vbs" FOOBAR

    缺点是需要额外的脚本,但不需要重启。

    【讨论】:

      【解决方案10】:

      顺便说一句,我刚刚弄清楚了如何取消设置您使用 setx 设置的永久变量。

      只需写引号,如:

      setx myvar ""
      

      如果您搜索变量,则在下一个 cmd 窗口重新启动时

      set myvar
      

      不会有任何设置。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-13
      • 1970-01-01
      • 2018-11-18
      • 2015-01-14
      • 1970-01-01
      • 2017-07-02
      • 1970-01-01
      相关资源
      最近更新 更多