Questo è stato trattato un bel po ', ma manca un'informazione cruciale. Spero di poter aiutare a chiarire come funziona e dare un po 'di sollievo ai viaggiatori stanchi. :-)
Elimina dal processo corrente
Ovviamente, tutti sanno che lo fai solo per eliminare una variabile d'ambiente dal tuo processo attuale:
set FOO=
Elimina persistente
Esistono due set di variabili di ambiente, a livello di sistema e utente.
Elimina variabile ambiente utente:
reg delete "HKCU\Environment" /v FOO /f
Elimina variabile di ambiente di sistema:
REG delete "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /F /V FOO
Applica valore senza riavviare
Ecco le informazioni magiche che mancano! Ti stai chiedendo perché dopo aver fatto questo, quando avvii una nuova finestra di comando, la variabile d'ambiente è ancora lì. Il motivo è perché explorer.exe non ha aggiornato il suo ambiente. Quando un processo ne avvia un altro, il nuovo processo eredita l'ambiente dal processo che lo ha avviato.
Esistono due modi per risolvere questo problema senza riavviare. Il modo più brutale è di interrompere il processo explorer.exe e riavviarlo. Puoi farlo da Task Manager . Non consiglio questo metodo, tuttavia.
L'altro modo è dire a explorer.exe che l'ambiente è cambiato e che dovrebbe rileggerlo. Questo viene fatto trasmettendo un messaggio di Windows (WM_SETTINGCHANGE). Questo può essere realizzato con un semplice script PowerShell. Potresti facilmente scriverne uno per farlo, ma ne ho trovato uno in Impostazioni finestra di aggiornamento dopo le modifiche tramite script :
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);
Sommario
Quindi, per eliminare una variabile di ambiente utente denominata "FOO" e fare in modo che la modifica si rifletta nei processi avviati successivamente, procedere come segue.
- Salvare lo script di PowerShell in un file (lo chiameremo updateenv.ps1).
- Fallo dalla riga di comando: reg delete "HKCU \ Environment" / v FOO / f
- Esegui updateenv.ps1.
- Chiudi e riapri il prompt dei comandi e vedrai che la variabile di ambiente non è più definita.
Nota, probabilmente dovrai aggiornare le impostazioni di PowerShell per permetterti di eseguire questo script, ma lo lascerò come esercizio di Google-fu per te.