用于从OS级别配置中删除环境变量的命令行

157 windows registry environment-variables

Windows有setx命令

Description:
    Creates or modifies environment variables in the user or system
    environment.
Run Code Online (Sandbox Code Playgroud)

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

setx FOOBAR 1
Run Code Online (Sandbox Code Playgroud)

你可以像这样清除价值

setx FOOBAR ""
Run Code Online (Sandbox Code Playgroud)

但是,变量不会被删除,它会保留在注册表中

foob​​ar的

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

Cup*_*Tae 185

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

set FOOBAR=
Run Code Online (Sandbox Code Playgroud)

要从用户环境中永久删除变量(这是默认位置setx):

REG delete HKCU\Environment /F /V FOOBAR
Run Code Online (Sandbox Code Playgroud)

如果在系统环境中设置了变量(例如,如果您最初设置了该变量setx /M),则作为管理员运行:

REG delete "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /F /V FOOBAR
Run Code Online (Sandbox Code Playgroud)

注意:上述REG命令不会影响任何现有进程(以及从现有进程分叉的一些新进程),因此如果更改立即生效很重要,您可能需要注销并重新登录或重新启动.

  • 这个解决方案似乎不起作用 - 或者我误解了一些基本的东西。我做“setx JUNK Hello”。打开新的cmd。输入“echo %JUNK%”并得到“Hello”。然后我执行`REG delete "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /F /V JUNK`,并确认该值已从注册表中消失。我打开新的 cmd 并输入“echo %JUNK%”,但仍然得到“Hello”。注册表搜索显示不存在“JUNK”。请不要告诉我您需要重新启动! (3认同)
  • 也许它只是语义,但删除(从注册表)立即生效.在您再次登录之前,不会从注册表重新初始化环境.您可以将两个命令组合在一起,将其从当前环境中删除(将其从下一个cmd shell的`SET`列表中删除),然后将其从注册表中删除,例如:`SETX FOOBAR""&REG删除HKCU \环境/ F/V FOOBAR` (3认同)

小智 71

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

set FOOBAR=

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

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

  • 这绝对不是答案,我觉得令人不安的是,有太多的选票.这仅对当前命令会话有效.启动一个新的命令窗口,然后返回var. (70认同)
  • @oberlies我不同意它回答了标题中的问题,因为这不适用于操作系统级别,但仅适用于当前命令窗口.其次,你的观点表明问题的细节部分是无关紧要的. (10认同)
  • @joescii你觉得这令人惊讶吗?这回答了问题标题中的问题.显然问题标题需要更加具体. (6认同)
  • @oberlies不幸的是编辑似乎没有完成这个伎俩 - 它仍然得到了提升.我猜人们发现即使它没有回答实际问题也很有用,在这种情况下,它可能值得赞成(是吗?).至少它没有标记为被接受,这会产生误导. (3认同)
  • 我应该评论为什么我投票失败。显然是因为这仅在当前会话中有效。 (3认同)
  • @Luke,因为我来到这里寻找一种在所有会话中取消它的方法 - 所以这个答案提供了我不想要的东西. (3认同)
  • 我到达这里寻找一种方法,只在当前会话中取消它 - 所以这个答案提供了我正在寻找的.只要答案与问题有关并明确界定其局限性,为什么还要投票? (2认同)

Jam*_*mie 22

这已经被覆盖了很多,但是缺少一条至关重要的信息.希望我能帮助澄清这是如何运作的,并给疲惫的旅行者带来一些缓解.:-)

从当前进程中删除

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

set FOO=
Run Code Online (Sandbox Code Playgroud)

持久删除

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

删除用户环境变量:

reg delete "HKCU\Environment" /v FOO /f
Run Code Online (Sandbox Code Playgroud)

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

REG delete "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /F /V FOO
Run Code Online (Sandbox Code Playgroud)

在不重新启动的情况下应用值

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

有两种方法可以在不重启的情况下解决此问题.最蛮力的方法是杀死您的explorer.exe进程并再次启动它.您可以从任务管理器执行此操作.但是,我不推荐这种方法.

另一种方法是告诉explorer.exe环境已经改变并且应该重新读取它.这是通过广播Windows消息(WM_SETTINGCHANGE)来完成的.这可以通过简单的Powershell脚本来完成.你可以轻松地写一个这样做,但我在这里找到一个:https://www.angryadmin.co.uk/?tag = wm_settingchange .

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);
Run Code Online (Sandbox Code Playgroud)

摘要

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

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

请注意,您可能需要更新您的Powershell设置以允许您运行此脚本,但我会将其作为Google-Foo练习留给您.


小智 13

同意CupawnTae.

SET 对主环境的更改没有用.

仅供参考:系统变量处于HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment (比用户变量更长的时间).

因此,对名为FOOBAR的系统var的完整命令是:( setx 注意处理空间所需的引号)

太糟糕了,该SET命令不支持删除语法.:(

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


Ron*_*ore 12

删除不重启

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
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 这是一个聪明的答案。 (2认同)

小智 11

上面的命令不起作用,但这样做:

reg delete "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v FOOBAR /f
Run Code Online (Sandbox Code Playgroud)

HKLM可以使用快捷方式HKEY_LOCAL_MACHINE.

  • @Tzrlk,必须再次在Windows端进行一些搞砸的设计. (2认同)

mkl*_*nt0 11

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

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

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

    [Environment]::SetEnvironmentVariable('FOO', $null, 'Machine')
    
    Run Code Online (Sandbox Code Playgroud)

除了执行速度更快外,reg.exe基于-方法的优点还在于,其他应用程序会通过一条WM_SETTINGCHANGE消息通知该更改(尽管并非所有应用程序都在监听该消息)。

  • 这是最好的答案。 (2认同)
  • 此方法避免了重新启动的需要。多么优雅的解决方案啊! (2认同)
  • @AlejandroGonzález - 这将在 .bat 脚本中工作: `powershell.exe -Command "[System.Environment]::SetEnvironmentVariable('FOO', $null, 'Machine')"` (2认同)

小智 6

setx FOOBAR ""
Run Code Online (Sandbox Code Playgroud)

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

我用了:

set FOOBAR=
Run Code Online (Sandbox Code Playgroud)

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

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

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