Командная строка для удаления переменной среды из конфигурации уровня ОС

В Windows есть команда setx :

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

Таким образом, вы можете установить переменную следующим образом:

setx FOOBAR 1

И вы можете очистить значение следующим образом:

setx FOOBAR ""

Однако переменная не удаляется. Он остается в реестре:

foobar

Итак, как бы вы на самом деле удалили переменную?

Ответ 1

Чтобы удалить переменную из текущей среды (не навсегда):

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, описанные выше, не влияют на существующие процессы (и некоторые новые процессы, которые разветвляются из существующих процессов), поэтому, если важно, чтобы изменение вступило в силу немедленно, вы может выйти из системы и снова войти или перезагрузиться.

Ответ 2

Чтобы удалить переменную из текущего сеанса команды, не удаляя ее постоянно, используйте регулярную встроенную команду set - просто не помещайте ничего после знака равенства:

set FOOBAR=

Чтобы подтвердить, запустите set без аргументов и проверьте текущую среду. Переменная должна отсутствовать в списке целиком.

Примечание: это приведет только к удалению переменной из текущей среды - она ​​не будет сохраняться в реестре. Когда будет запущен новый командный процесс, переменная вернется.

Ответ 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 и запустить его снова. Вы можете сделать это из диспетчера задач. Однако я не рекомендую этот метод.

Другой способ - сообщить 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 для вас.

Ответ 4

Я согласен с CupawnTae.

SET бесполезен для изменений в основной среде.

К вашему сведению: системные переменные находятся в HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment (намного дольше, чем пользовательские переменные).

Поэтому полная команда для системной переменной с именем FOOBAR выглядит так:

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

(обратите внимание на кавычки, необходимые для обработки пробела.)

Очень плохо, что команда setx не поддерживает синтаксис удаления. :(

PS: Используйте ответственно - если вы убьете свою переменную пути, не вините меня!

Ответ 5

Команда в ответе DougWare не сработала, но это сработало:

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

Ярлык HKLM можно использовать для HKEY_LOCAL_MACHINE.

Ответ 6

Из PowerShell вы можете использовать метод .NET [System.Environment]::SetEnvironmentVariable() :

  • Чтобы удалить переменную среды пользователя с именем FOO:

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

Note that [TG43] is used to better signal the intent to remove the variable, though technically it is effectively the same as passing [TG44] in this case.

  • Чтобы удалить системную (машинную) переменную среды с именем FOO - требуется повышение прав (необходимо запускать с правами администратора):

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

Помимо более быстрого выполнения, преимущество по сравнению с методом reg.exe -based заключается в том, что другие приложения уведомляются об изменении через сообщение WM_SETTINGCHANGE (хотя не все приложения слушают на это сообщение).

Ответ 7

setx FOOBAR ""

просто заставляет значение FOOBAR быть пустой строкой. (Хотя это показывается командой set с "", поэтому, возможно, двойные кавычки - это строка.)

Я использовал:

set FOOBAR=

а затем FOOBAR больше не был указан в команде set. (Выход не требуется.)

Windows 7 32-разрядная, используя командную строку, не администратор это то, что я использовал. (Не cmd или Windows + R, которые могут отличаться.)

Кстати, я не видел переменную, которую я создал где-то в реестре после того, как я ее создал. Я использую RegEdit не как администратор.

Ответ 8

Вы также можете создать небольшой 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.

Недостаток в том, что вам нужен дополнительный скрипт, но он не требует перезагрузки.