windows 从操作系统级别配置中删除环境变量的命令行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13222724/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 10:02:22  来源:igfitidea点击:

Command line to remove an environment variable from the OS level configuration

windowsregistryenvironment-variables

提问by CupawnTae

Windows has the setxcommand:

Windows 有以下setx命令:

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

So you can set a variable like this:

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

setx FOOBAR 1

And you can clear the value like this:

您可以像这样清除值:

setx FOOBAR ""

However, the variable does not get removed. It stays in the registry:

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

foobar

食物吧

So how would you actually remove the variable?

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

回答by CupawnTae

To remove the variable from the current environment (notpermanently):

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

set FOOBAR=

To permanently remove the variable from the userenvironment (which is the default place setxputs it):

要从用户环境中永久删除变量(这是默认放置setx它的地方):

REG delete HKCU\Environment /F /V FOOBAR

If the variable is set in the systemenvironment (e.g. if you originally set it with setx /M), as an administrator run:

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

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

Note: The REGcommands above won't affect any existing processes (and some new processes that are forked from existing processes), so if it's important for the change to take effect immediately, the easiest and surest thing to do is log out and back in or reboot. If this isn't an option or you want to dig deeper, some of the other answers here have some great suggestions that may suit your use case.

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

回答by Brian Kelly

To remove the variable from the current command session without removing it permanently, use the regular built-in setcommand - just put nothing after the equals sign:

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

set FOOBAR=

set FOOBAR=

To confirm, run setwith no arguments and check the current environment. The variable should be missing from the list entirely.

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

Note: this will only remove the variable from the current environment- it will not persist the change to the registry. When a new command process is started, the variable will be back.

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

回答by Jamie

This has been covered quite a bit, but there's a crucial piece of information that's missing. Hopefully, I can help to clear up how this works and give some relief to weary travellers. :-)

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

Delete From Current Process

从当前进程中删除

Obviously, everyone knows that you just do this to delete an environment variable from your current process:

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

set FOO=

Persistent Delete

永久删除

There are two sets of environment variables, system-wide and user.

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

Delete User Environment Variable:

删除用户环境变量:

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

Delete System-Wide Environment Variable:

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

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

Apply Value Without Rebooting

无需重新启动即可应用值

Here's the magic information that's missing! You're wondering why after you do this, when you launch a new command window, the environment variable is still there. The reason is because explorer.exe has not updated its environment. When one process launches another, the new process inherits the environment from the process that launched it.

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

There are two ways to fix this without rebooting. The most brute-force way is to kill your explorer.exe process and start it again. You can do that from Task Manager. I don't recommend this method, however.

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

The other way is by telling explorer.exe that the environment has changed and that it should reread it. This is done by broadcasting a Windows message (WM_SETTINGCHANGE). This can be accomplished with a simple PowerShell script. You could easily write one to do this, but I found one in Update Window Settings After Scripted Changes:

另一种方法是告诉 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);

Summary

概括

So to delete a user environment variable named "FOO" and have the change reflected in processes you launch afterwards, do the following.

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

  1. Save the PowerShell script to a file (we'll call it updateenv.ps1).
  2. Do this from the command line: reg delete "HKCU\Environment" /v FOO /f
  3. Run updateenv.ps1.
  4. Close and reopen your command prompt, and you'll see that the environment variable is no longer defined.
  1. 将 PowerShell 脚本保存到一个文件中(我们将其命名为 updateenv.ps1)。
  2. 从命令行执行此操作:reg delete "HKCU\Environment" /v FOO /f
  3. 运行 updateenv.ps1。
  4. 关闭并重新打开命令提示符,您将看到不再定义环境变量。

Note, you'll probably have to update your PowerShell settings to allow you to run this script, but I'll leave that as a Google-fu exercise for you.

请注意,您可能需要更新 PowerShell 设置才能运行此脚本,但我会将其留作 Google-fu 练习。

回答by mklement0

From PowerShellyou can use the .NET [System.Environment]::SetEnvironmentVariable()method:

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

  • To remove a userenvironment variablenamed FOO:

    [Environment]::SetEnvironmentVariable('FOO', $null, 'User')
    
  • 删除用户环境变量命名为FOO

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

Note that $nullis used to better signal the intent to removethe variable, though technically it is effectively the same as passing ''in this case.

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

  • To remove a system(machine-level) environment variablenamed FOO- requires elevation(must be run as administrator):

    [Environment]::SetEnvironmentVariable('FOO', $null, 'Machine')
    
  • 删除名为FOO-需要提升(必须以管理员身份运行系统(机器级)环境变量

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

Aside from faster execution, the advantage over the reg.exe-based methodis that other applications are notified of the change, via a WM_SETTINGCHANGEmessage (though not all applications listen to that message).

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

回答by DougWare

I agree with CupawnTae.

我同意CupawnTae

SETis not useful for changes to the master environment.

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

FYI: System variables are in HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment(a good deal longer than user vars).

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

The full command for a system var named FOOBAR therefore is:

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

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

(Note the quotes required to handle the space.)

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

It is too bad the setxcommand doesn't support a delete syntax. :(

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

PS: Use responsibly - If you kill your path variable, don't blame me!

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

回答by user4297498

The command in DougWare's answerdid not work, but this did:

DougWare 的回答中的命令不起作用,但这样做了:

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

The shortcut HKLMcan be used for HKEY_LOCAL_MACHINE.

快捷方式HKLM可用于HKEY_LOCAL_MACHINE.

回答by PReinie

setx FOOBAR ""

just causes the value of FOOBAR to be a null string. (Although, it shows with the setcommand with the "" so maybe double-quotes is the string.)

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

I used:

我用了:

set FOOBAR=

and then FOOBAR was no longer listed in the set command. (Log-off was not required.)

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

Windows 7 32 bit, using the command prompt, non-administrator is what I used. (Not cmd or Windows+ R, which might be different.)

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

BTW, I did not see the variable I created anywhere in the registry after I created it. I'm using RegEditnot as administrator.

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

回答by Ronny D'Hoore

Delete Without Rebooting

删除不重启

The OP's question indeed has been answered extensively, including how to avoid rebooting through powershell, vbscript, or you name it.

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

However, if you need to stick to cmd commands only and don't have the luxury of being able to call powershell or vbscript, you could use the following approach:

但是,如果您只需要坚持使用 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

So the magic here is that by using "setx" to assign something to a variable you don't need (in my example DUMMY), you force Explorer.exe to reread the variables from the registry, without needing powershell. You then clean up that dummy, and even though that one will stay in Explorer's environment for a little while longer, it will probably not harm anyone.

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

Or if after deleting variables you need to set new ones, then you don't even need any dummy. Just using SETX to set the new variables will automatically clear the ones you just removed from any new cmd tasks that might get started.

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

Background information: I just used this approach successfully to replace a set of user variables by system variables of the same name on all of the computers at my job, by modifying an existing cmd script. There are too many computers to do it manually, nor was it practical to copy extra powershell or vbscripts to all of them. The reason I urgently needed to replace user with system variables was that user variables get synchronized in roaming profiles (didn't think about that), so multiple machines using the same windows login but needing different values, got mixed up.

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

回答by Wernfried Domscheit

You can also create a small VBScriptscript:

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

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

Then call it like %windir%\System32\cscript.exe //Nologo "script_name.vbs" FOOBAR.

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

The disadvantage is you need an extra script, but it does not require a reboot.

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