233

Windows 有setx命令:

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

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

setx FOOBAR 1

您可以像这样清除值:

setx FOOBAR ""

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

富吧

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

4

10 回答 10

281

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

set FOOBAR=

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

REG delete HKCU\Environment /F /V FOOBAR

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

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

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

于 2012-11-04T20:52:54.350 回答
72

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

set FOOBAR=

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

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

于 2014-01-27T14:47:29.123 回答
35

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

从当前进程中删除

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

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 进程并重新启动它。您可以从任务管理器中执行此操作。但是,我不推荐这种方法。

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

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 练习留给您。

于 2018-02-15T21:08:37.020 回答
34

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

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

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

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

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

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

除了更快的执行之外,reg.exe基于 -based 方法的优点是其他应用程序通过WM_SETTINGCHANGE消息通知更改(尽管并非所有应用程序都侦听该消息)。

于 2018-10-08T18:12:10.790 回答
15

我同意CupawnTae 的观点

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

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

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

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

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

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

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

于 2014-05-14T20:28:39.627 回答
14

不重启就删除

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 登录但需要不同值的多台机器混淆了。

于 2019-11-18T14:52:24.690 回答
11

DougWare 的答案中的命令不起作用,但确实如此:

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

该快捷方式HKLM可用于HKEY_LOCAL_MACHINE.

于 2014-11-26T19:44:44.153 回答
6
setx FOOBAR ""

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

我用了:

set FOOBAR=

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

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

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

于 2017-06-05T23:33:57.037 回答
2

您还可以创建一个小的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.

缺点是您需要一个额外的脚本,但它不需要重新启动。

于 2018-09-13T11:34:36.360 回答
1

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

只需写引号,例如:

setx myvar ""

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

set myvar

不会有任何设置。

于 2021-11-08T13:39:30.200 回答