Riga di comando per rimuovere una variabile di ambiente dalla configurazione a livello di sistema operativo


182

Windows ha il setxcomando:

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

Quindi puoi impostare una variabile come questa:

setx FOOBAR 1

E puoi cancellare il valore in questo modo:

setx FOOBAR ""

Tuttavia, la variabile non viene rimossa. Rimane nel registro:

foobar

Quindi come rimuoveresti la variabile?


3
setx imposta solo la variabile. Lo stai semplicemente cancellando con quella linea.
Fox Wilson,


Dal momento che mi ci è voluto un bel po 'di scavo, vedi anche superuser.com/q/297947/46834 per le opzioni non a riga di comando.
gary,

Risposte:


217

Per rimuovere la variabile dall'ambiente corrente ( non in modo permanente):

set FOOBAR=

Per rimuovere definitivamente la variabile dall'ambiente utente (che è la posizione predefinita la setxmette):

REG delete HKCU\Environment /F /V FOOBAR

Se la variabile è impostata nell'ambiente di sistema (ad esempio se è stata originariamente impostata con setx /M), come amministratore eseguire:

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

Nota: i REGcomandi precedenti non influiranno su alcun processo esistente (e su alcuni nuovi processi che sono biforcuti da processi esistenti), quindi se è importante che la modifica abbia effetto immediato, la cosa più semplice e sicura da fare è disconnettersi e riconnettersi o riavviare. Se questa non è un'opzione o vuoi approfondire, alcune delle altre risposte qui hanno alcuni ottimi suggerimenti che potrebbero adattarsi al tuo caso d'uso.


1
Questa soluzione non sembra funzionare - o sto fraintendendo qualcosa di base. Lo faccio setx JUNK Hello. Apri nuovo cmd. Digita echo %JUNK%e ottieni Hello. Quindi lo faccio REG delete "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /F /V JUNKe confermo che il valore è passato dal registro. Apro nuovo cmd e digito echo %JUNK%e ancora ottengo Hello. La ricerca nel registro non mostra presenza di "JUNK". Per favore, non dirmi che hai bisogno di un riavvio!
Caasjj,

Grazie per la risposta. Sto aprendo una nuova finestra di comando dal menu Start. Ho provato entrambe le versioni del comando. In effetti, la prima volta che digito il usercomando environment, ha esito positivo. Quindi, quando digito nuovamente il comando, ottengo The system was unable to find the specified registry or key value. Inoltre, una ricerca globale JUNKnel registro con regeditnon presenta nulla. Tuttavia, quando apro una nuova finestra di comando (tramite Start / accessori o cmd.exe in Esegui) e digito echo %JUNK%, il valore è ancora lì!
Caasjj,

1
Ah! Cosa pensi che sia razionale per quello ?? Evito sempre l'amministratore il più possibile - educazione UNIX / BSD / Linux. Grazie mille per la straordinaria diligenza. +1
caasjj,

4
forse è solo una semantica, ma la cancellazione (dal registro) ha effetto immediato. L'ambiente non viene inizializzato nuovamente dal registro fino a quando non si accede nuovamente. È possibile combinare i 2 comandi per rimuoverlo dall'ambiente corrente (che lo rimuoverà SETdall'elenco per la prossima shell cmd) e quindi rimuoverlo dal registro, ad esempio:SETX FOOBAR "" & REG delete HKCU\Environment /F /V FOOBAR
Luca

1
Il motivo per cui l'ambiente non sembra essere aggiornato senza riavviare è perché explorer.exe non sa che è stato aggiornato. Vedi la mia risposta per una spiegazione e una soluzione complete.
Jamie,

72

Per rimuovere la variabile dalla sessione di comando corrente senza rimuoverla permanentemente, utilizzare il normale setcomando incorporato : basta inserire nulla dopo il segno di uguale:

set FOOBAR=

Per confermare, esegui setsenza argomenti e controlla l'ambiente corrente. La variabile dovrebbe mancare completamente dall'elenco.

Nota : questo rimuoverà solo la variabile dall'ambiente corrente - non persisterà la modifica al registro. Quando viene avviato un nuovo processo di comando, la variabile tornerà.


77
Questa NON è sicuramente la risposta, e trovo inquietante che ci siano così tanti voti positivi. Questo è efficace solo per la sessione di comando corrente. Apri una nuova finestra di comando e il var è tornato.
joescii,

6
@joescii Lo trovi sorprendente? Ciò ha risposto alla domanda nel titolo della domanda. Quindi ovviamente il titolo della domanda doveva essere più specifico.
oberlies,

10
@oberlies Non sono d'accordo sul fatto che risponda alla domanda nel titolo, perché NON funziona a livello di sistema operativo, ma solo nella finestra di comando corrente. In secondo luogo, il tuo punto suggerisce che la parte relativa ai dettagli della domanda è irrilevante.
joescii,

3
@oberlies purtroppo la modifica non sembra aver fatto il trucco - sta ancora ottenendo voti. Immagino che le persone lo trovino utile anche se non risponde alla vera domanda, nel qual caso forse merita i voti (vero?). Almeno non è contrassegnato come accettato, il che sarebbe fuorviante.
CupawnTae

3
Dovrei commentare il motivo per cui ho effettuato il downgrade. Ovviamente perché questo funziona solo nella sessione corrente.
Ian Grainger,

22

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.

  1. Salvare lo script di PowerShell in un file (lo chiameremo updateenv.ps1).
  2. Fallo dalla riga di comando: reg delete "HKCU \ Environment" / v FOO / f
  3. Esegui updateenv.ps1.
  4. 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.


C'è qualche motivo particolare per cui non consigli di uccidere e riavviare explorer? Lo faccio tutto il tempo.
Prometeo

Bene, ce ne sono due che mi vengono in mente per primi. Il primo è che i processi di uccisione forzata possono causare perdite di memoria. Sì, i processi dovrebbero essere sand-box, ma anche il Task Manager di Windows ti avvisa di non farlo alla leggera. L'altro motivo più personale è il mio disturbo ossessivo compulsivo. Quando si annulla e si riavvia Explorer, tutte le icone in basso nella barra delle attività, inclusi i duplicati quando si fa clic su uno, vengono riorganizzate. Mi piace che le mie icone rimangano nell'ordine in cui ho aperto le cose.
Jamie,

1
Wow. Il comando magico che stavo cercando è simile a source .bashrc(o ai suoi cugini) in Windows. Questo va in cima alla riga "riferisci a questo" per me.
bballdave025,

19

Da PowerShell è possibile utilizzare il [System.Environment]::SetEnvironmentVariable()metodo .NET :

  • Per rimuovere una variabile di ambiente utente denominata FOO:

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

Si noti che $nullviene utilizzato per segnalare meglio l'intenzione di rimuovere la variabile, sebbene tecnicamente sia effettivamente lo stesso che passare ''in questo caso.

  • Per rimuovere una variabile di ambiente di sistema (a livello di macchina) denominata FOO- richiede elevazione (deve essere eseguita come amministratore):

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

A parte un'esecuzione più rapida, il vantaggio rispetto al reg.exemetodo basato su è che le altre applicazioni vengono informate della modifica , tramite un WM_SETTINGCHANGEmessaggio (sebbene non tutte le applicazioni ascoltino quel messaggio).


2
Questa è la migliore risposta qui.
James,

1
Questo metodo evita la necessità di riavviare. Che soluzione elegante!
jyao,

13

Sono d'accordo con CupawnTae .

SET non è utile per le modifiche all'ambiente principale.

Cordiali saluti: le variabili di sistema sono presenti HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment(molto più a lungo delle varianti dell'utente).

Il comando completo per una var di sistema denominata FOOBAR è quindi:

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

(Nota le virgolette necessarie per gestire lo spazio.)

Peccato che il setxcomando non supporti una sintassi di eliminazione. :(

PS: usa responsabilmente - Se uccidi la tua variabile path, non incolparmi!


@CMCDragonkai che è esplicitamente menzionato nella domanda originale: non rimuove la voce di registro, ma la cancella. La
vera

1
Vorrei solo aggiungere che potrebbe essere necessario riavviare / aggiornare cmd prima che abbia effetto.
jiggunjer,

@jiggunjer, Come aggiornare?
Pacerier,

@Pacerier ha appena aperto un nuovo terminale.
jiggunjer,

11

Il comando nella risposta di DougWare non ha funzionato, ma questo ha funzionato:

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

È HKLMpossibile utilizzare il collegamento per HKEY_LOCAL_MACHINE.


1
Inoltre, le variabili di ambiente dell'utente si trovano in "HKCU \ Environment"
tzrlk,

1
@Tzrlk, qual è il motivo della mancata corrispondenza? Perché non è in HKLM \ Environment lì?
Pacerier,

@Pacerier: non ho idea del perché li inseriscano in posizioni così completamente separate, ma se vuoi assicurarti di aver rimosso le variabili / system o / e user, aiuta a sapere che sono completamente diverse posti.
tzrlk,

2
@Tzrlk, Deve essere di nuovo un design avvitato sul lato di Windows.
Pacerier,

4

Elimina senza riavviare

Alla domanda del PO è stata infatti data ampia risposta, incluso come evitare il riavvio tramite PowerShell, vbscript o come si chiama.

Tuttavia, se è necessario attenersi solo ai comandi cmd e non si ha il lusso di poter chiamare PowerShell o vbscript, è possibile utilizzare il seguente approccio:

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

Quindi la magia qui è che usando "setx" per assegnare qualcosa a una variabile non necessaria (nel mio esempio DUMMY), si forza Explorer.exe a rileggere le variabili dal registro, senza bisogno di PowerShell. Quindi ripulisci quel manichino, e anche se uno rimarrà nell'ambiente di Explorer per un po 'più a lungo, probabilmente non danneggerà nessuno.

O se dopo aver eliminato le variabili è necessario impostarne di nuove, non è nemmeno necessario alcun manichino. Il solo utilizzo di SETX per impostare le nuove variabili cancella automaticamente quelle appena rimosse da eventuali nuove attività cmd che potrebbero essere avviate.

Informazioni di base: ho appena usato questo approccio con successo per sostituire un set di variabili utente con variabili di sistema con lo stesso nome su tutti i computer del mio lavoro, modificando uno script cmd esistente. Ci sono troppi computer per farlo manualmente, né è stato pratico copiare extra PowerShell o vbscripts su tutti. Il motivo per cui avevo urgente bisogno di sostituire l'utente con le variabili di sistema era che le variabili utente venivano sincronizzate nei profili di roaming (non ci pensavo), quindi più macchine che utilizzavano lo stesso login di Windows ma necessitavano di valori diversi, si confondevano.


3
setx FOOBAR ""

fa sì che il valore di FOOBAR sia una stringa nulla. (Anche se, mostra con il setcomando "", quindi forse la virgoletta è la stringa.)

Ero solito:

set FOOBAR=

e quindi FOOBAR non era più elencato nel comando set. (Non è stato necessario disconnettersi.)

Windows 7 a 32 bit, utilizzando il prompt dei comandi, non amministratore è quello che ho usato. (Non cmd o Windows+ R, che potrebbe essere diverso.)

A proposito, non ho visto la variabile che ho creato da nessuna parte nel registro dopo averlo creato. Sto usando RegEdit non come amministratore.


1

Puoi anche creare un piccolo script VBScript :

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

Quindi chiamalo come %windir%\System32\cscript.exe //Nologo "script_name.vbs" FOOBAR.

Lo svantaggio è che è necessario uno script aggiuntivo, ma non richiede un riavvio.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.