Baris perintah untuk menghapus variabel lingkungan dari konfigurasi level OS

182

Windows memiliki setxperintah:

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

Jadi, Anda dapat mengatur variabel seperti ini:

setx FOOBAR 1

Dan Anda dapat menghapus nilai seperti ini:

setx FOOBAR ""

Namun, variabel tidak dihapus. Itu tetap dalam registri:

foobar

Jadi bagaimana Anda benar-benar menghapus variabel?

Peter Mortensen
sumber
3
setx hanya mengatur variabel. Anda hanya mengosongkannya dengan garis itu.
Fox Wilson
1
lihat juga stackoverflow.com/questions/1472722/...
Brian Burns
Karena saya butuh cukup banyak penggalian, lihat juga superuser.com/q/297947/46834 untuk opsi baris non-perintah.
gary

Jawaban:

217

Untuk menghapus variabel dari lingkungan saat ini ( tidak secara permanen):

set FOOBAR=

Untuk secara permanen menghapus variabel dari lingkungan pengguna (yang merupakan tempat default setxmeletakkannya):

REG delete HKCU\Environment /F /V FOOBAR

Jika variabel diatur dalam lingkungan sistem (mis. Jika Anda awalnya mengaturnya dengan setx /M), sebagai administrator jalankan:

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

Catatan: REGPerintah di atas tidak akan memengaruhi proses yang ada (dan beberapa proses baru yang bercabang dari proses yang ada), jadi jika penting agar perubahan segera berlaku, hal termudah dan paling pasti untuk dilakukan adalah keluar dan kembali atau reboot. Jika ini bukan pilihan atau Anda ingin menggali lebih dalam, beberapa jawaban lain di sini memiliki beberapa saran bagus yang mungkin sesuai dengan kasus penggunaan Anda.

CupawnTae
sumber
1
Solusi ini sepertinya tidak berhasil - atau saya salah memahami sesuatu yang mendasar. Saya lakukan setx JUNK Hello. Buka cmd baru. Ketik echo %JUNK%dan dapatkan Hello. Lalu saya lakukan REG delete "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /F /V JUNK, dan konfirmasikan bahwa nilai hilang dari registri. Saya membuka cmd dan ketik baru echo %JUNK%dan masih mendapatkan Hello. Pencarian registri tidak menunjukkan kehadiran 'JUNK'. Tolong jangan bilang Anda perlu reboot!
caasjj
Terima kasih balasannya. Saya membuka jendela perintah baru dari menu Mulai. Saya telah mencoba kedua versi perintah. Bahkan, pertama kali ketika saya mengetik userperintah lingkungan, berhasil. Kemudian, ketika saya mengetik ulang perintah yang saya dapatkan The system was unable to find the specified registry or key value. Juga, pencarian global JUNKdalam registri dengan regedittidak menemukan apa pun. Namun, ketika saya membuka jendela Command baru (melalui Start / accessories, atau cmd.exe di Run) dan ketik echo %JUNK%, nilainya masih ada di sana!
caasjj
1
Ah! Menurut Anda apa alasannya untuk itu ?? Saya selalu menghindari admin sebanyak mungkin - asuhan UNIX / BSD / Linux. Terima kasih banyak untuk ketekunan yang luar biasa. +1
caasjj
4
mungkin itu hanya semantik, tetapi penghapusan (dari registri) segera berlaku. Lingkungan tidak diinisialisasi ulang dari registri hingga Anda masuk lagi. Anda dapat menggabungkan 2 perintah untuk menghapusnya dari lingkungan saat ini (yang akan menghapusnya dari SETdaftar untuk shell cmd berikutnya) dan kemudian menghapusnya dari registri, misalnya:SETX FOOBAR "" & REG delete HKCU\Environment /F /V FOOBAR
Luke
1
Alasan mengapa lingkungan tampaknya tidak diperbarui tanpa me-reboot adalah karena explorer.exe tidak tahu bahwa itu telah diperbarui. Lihat jawaban saya untuk penjelasan dan solusi lengkap.
Jamie
72

Untuk menghapus variabel dari sesi perintah saat ini tanpa menghapusnya secara permanen, gunakan perintah built-in reguler set- cukup masukkan apa pun setelah tanda sama dengan:

set FOOBAR=

Untuk mengonfirmasi, jalankan settanpa argumen dan periksa lingkungan saat ini. Variabel harus hilang dari daftar sepenuhnya.

Catatan : ini hanya akan menghapus variabel dari lingkungan saat ini - tidak akan mempertahankan perubahan ke registri. Ketika proses perintah baru dimulai, variabel akan kembali.

Brian Kelly
sumber
77
Ini jelas BUKAN jawabannya, dan saya merasa terganggu karena ada begitu banyak suara. Ini hanya efektif untuk sesi perintah saat ini. Crank jendela perintah baru, dan var kembali.
joescii
6
@joescii Anda menemukan ini mengejutkan? Ini menjawab pertanyaan dalam judul pertanyaan. Jadi jelas judul pertanyaan harus lebih spesifik.
Oberlies
10
@oberlies Saya tidak setuju bahwa itu menjawab pertanyaan dalam judul, karena ini TIDAK bekerja di tingkat OS, tetapi hanya di jendela perintah saat ini. Kedua, poin Anda menunjukkan bahwa bagian detail dari pertanyaan itu tidak relevan.
joescii
3
@oberlies sayangnya hasil edit sepertinya tidak berhasil - masih mendapatkan upvotes. Saya kira orang-orang menganggapnya berguna bahkan jika itu tidak menjawab pertanyaan yang sebenarnya, dalam hal mana mungkin layak menerima upvote (bukan?). Setidaknya itu tidak ditandai sebagai diterima, yang akan menyesatkan.
CupawnTae
3
Saya seharusnya berkomentar mengapa saya downvoted. Jelas karena ini hanya berfungsi di sesi saat ini.
Ian Grainger
22

Ini sudah dibahas sedikit, tetapi ada informasi penting yang hilang. Semoga, saya bisa membantu menjernihkan cara kerjanya dan memberikan kelegaan bagi para pelancong yang lelah. :-)

Hapus Dari Proses Saat Ini

Jelas, semua orang tahu bahwa Anda hanya melakukan ini untuk menghapus variabel lingkungan dari proses Anda saat ini:

set FOO=

Hapus Persisten

Ada dua set variabel lingkungan, sistem-lebar dan pengguna.

Hapus Variabel Lingkungan Pengguna:

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

Hapus Variabel Lingkungan Luas Sistem:

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

Terapkan Nilai Tanpa Memulai Ulang

Inilah informasi ajaib yang hilang! Anda bertanya-tanya mengapa setelah Anda melakukan ini, ketika Anda meluncurkan jendela perintah baru, variabel lingkungan masih ada. Alasannya adalah karena explorer.exe belum memperbarui lingkungannya. Ketika satu proses meluncurkan yang lain, proses baru mewarisi lingkungan dari proses yang diluncurkan itu.

Ada dua cara untuk memperbaikinya tanpa me-reboot. Cara yang paling kasar adalah dengan mematikan proses explorer.exe Anda dan mulai lagi. Anda dapat melakukannya dari Task Manager . Saya tidak merekomendasikan metode ini.

Cara lain adalah dengan memberi tahu explorer.exe bahwa lingkungan telah berubah dan harus membacanya ulang. Ini dilakukan dengan menyiarkan pesan Windows (WM_SETTINGCHANGE). Ini dapat dilakukan dengan skrip PowerShell sederhana. Anda dapat dengan mudah menulis satu untuk melakukan ini, tetapi saya menemukan satu di Perbarui Pengaturan Jendela Setelah Perubahan 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);

Ringkasan

Jadi untuk menghapus variabel lingkungan pengguna yang bernama "FOO" dan memiliki perubahan yang tercermin dalam proses yang Anda luncurkan setelahnya, lakukan hal berikut.

  1. Simpan skrip PowerShell ke file (kami akan menyebutnya updateenv.ps1).
  2. Lakukan ini dari baris perintah: reg hapus "HKCU \ Environment" / v FOO / f
  3. Jalankan updateenv.ps1.
  4. Tutup dan buka kembali prompt perintah Anda, dan Anda akan melihat bahwa variabel lingkungan tidak lagi ditentukan.

Catatan, Anda mungkin harus memperbarui pengaturan PowerShell Anda untuk memungkinkan Anda menjalankan skrip ini, tetapi saya akan membiarkannya sebagai latihan Google-fu untuk Anda.

Jamie
sumber
Apakah ada alasan khusus mengapa Anda tidak merekomendasikan untuk membunuh dan memulai kembali explorer? Saya selalu melakukannya.
Prometheus
Nah, ada dua yang pertama kali terlintas dalam pikiran. Yang pertama adalah proses pembunuhan paksa dapat menyebabkan kebocoran memori. Ya, proses seharusnya kotak pasir, tetapi bahkan Windows Task Manager memperingatkan Anda untuk tidak melakukan ini dengan ringan. Alasan lain yang lebih pribadi adalah OCD saya. Saat Anda membunuh dan memulai ulang Explorer, semua ikon Anda di bilah tugas, termasuk duplikat saat Anda mengklik salah satunya, disusun ulang. Saya suka agar ikon saya tetap dalam urutan yang saya buka.
Jamie
1
Wow. Perintah ajaib yang saya cari itu bertindak seperti source .bashrc(atau sepupunya) di Windows. Ini menuju ke bagian atas baris "rujuk ke ini" untuk saya.
bballdave025
19

Dari PowerShell Anda dapat menggunakan [System.Environment]::SetEnvironmentVariable()metode .NET :

  • Untuk menghapus variabel lingkungan pengguna bernama FOO:

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

Catatan yang $nulldigunakan untuk memberi sinyal lebih baik niat untuk menghapus variabel, meskipun secara teknis itu sama dengan melewati ''dalam kasus ini.

  • Untuk menghapus variabel lingkungan sistem (level mesin) bernama FOO- memerlukan elevasi (harus dijalankan sebagai administrator):

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

Selain dari eksekusi yang lebih cepat, keuntungan dari reg.exemetode berbasis adalah bahwa aplikasi lain diberitahu tentang perubahan , melalui WM_SETTINGCHANGEpesan (meskipun tidak semua aplikasi mendengarkan pesan itu).

mklement0
sumber
2
Ini jawaban terbaik di sini.
James
1
Metode ini menghindari perlunya me-reboot. Solusi yang elegan!
jyao
13

Saya setuju dengan CupawnTae .

SET tidak berguna untuk perubahan pada lingkungan master.

FYI: Variabel sistem berada dalam HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment(jauh lebih lama daripada vars pengguna).

Perintah penuh untuk sistem var bernama FOOBAR karena itu adalah:

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

(Perhatikan kutipan yang diperlukan untuk menangani spasi.)

Sayang sekali setxperintahnya tidak mendukung sintaks hapus. :(

PS: Gunakan dengan bertanggung jawab - Jika Anda membunuh variabel jalur Anda, jangan salahkan saya!

DougWare
sumber
@ CMCDragonkai yang secara eksplisit disebutkan dalam pertanyaan asli - tidak menghapus entri registri, itu hanya kosong saja. Pertanyaan aktual adalah bagaimana cara menghapusnya dari registri
CupawnTae
1
Saya baru saja menambahkan Anda mungkin perlu me-restart / menyegarkan cmd sebelum ini berlaku.
jiggunjer
@ jiggunjer, Bagaimana cara menyegarkan?
Pacerier
@ Peracerier baru saja membuka terminal baru.
jiggunjer
11

Perintah dalam jawaban DougWare tidak berfungsi, tetapi ini berhasil:

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

Pintasan HKLMdapat digunakan untuk HKEY_LOCAL_MACHINE.

pengguna4297498
sumber
1
Juga, variabel lingkungan pengguna berada di bawah "HKCU \ Environment"
tzrlk
1
@Tzrlk, Apa alasan ketidakcocokan? Mengapa tidak ada di HKLM \ Environment di sana?
Pacerier
@Pacerier: Saya tidak tahu mengapa mereka menempatkan mereka di lokasi yang benar-benar terpisah, tetapi jika Anda ingin memastikan bahwa Anda telah menghapus salah satu / kedua sistem atau / dan variabel pengguna, akan membantu untuk mengetahui bahwa mereka berada di tempat yang benar - benar berbeda. tempat
tzrlk
2
@ Tzrlk, Harus ada beberapa desain yang kacau di sisi Windows lagi.
Pacerier
4

Hapus Tanpa Memulai Ulang

Pertanyaan OP memang telah dijawab secara luas, termasuk bagaimana menghindari reboot melalui PowerShell, VBScript, atau apa saja.

Namun, jika Anda harus tetap berpegang pada perintah cmd saja dan tidak memiliki kemewahan untuk dapat memanggil powershell atau vbscript, Anda bisa menggunakan pendekatan berikut:

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

Jadi keajaiban di sini adalah bahwa dengan menggunakan "setx" untuk menetapkan sesuatu ke variabel yang tidak Anda butuhkan (dalam contoh saya DUMMY), Anda memaksa Explorer.exe untuk membaca ulang variabel dari registri, tanpa memerlukan PowerShell. Anda kemudian membersihkan boneka itu, dan meskipun itu akan tetap berada di lingkungan Explorer sebentar, mungkin tidak akan membahayakan siapa pun.

Atau jika setelah menghapus variabel Anda perlu mengatur yang baru, maka Anda bahkan tidak perlu dummy. Hanya dengan menggunakan SETX untuk mengatur variabel baru akan secara otomatis menghapus variabel yang baru saja Anda hapus dari tugas cmd baru yang mungkin memulai.

Informasi latar belakang: Saya baru saja menggunakan pendekatan ini berhasil menggantikan satu set variabel pengguna dengan variabel sistem dengan nama yang sama di semua komputer di pekerjaan saya, dengan memodifikasi skrip cmd yang ada. Ada terlalu banyak komputer untuk melakukannya secara manual, juga tidak praktis untuk menyalin skrip powershell atau vbs tambahan ke semuanya. Alasan saya sangat diperlukan untuk mengganti pengguna dengan variabel sistem adalah bahwa variabel pengguna disinkronkan dalam profil roaming (tidak berpikir tentang itu), sehingga beberapa mesin menggunakan login windows yang sama tetapi membutuhkan nilai yang berbeda, digabungkan.

Ronny D'Hoore
sumber
3
setx FOOBAR ""

hanya menyebabkan nilai FOOBAR menjadi string nol. (Meskipun, itu terlihat denganset perintah dengan "" jadi mungkin tanda kutip ganda adalah string.)

Saya menggunakan:

set FOOBAR=

dan kemudian FOOBAR tidak lagi terdaftar dalam perintah yang ditetapkan. (Log-off tidak diperlukan.)

Windows 7 32 bit, menggunakan command prompt, non-administrator adalah apa yang saya gunakan. (Tidak cmd atau Windows+R , yang mungkin berbeda.)

BTW, saya tidak melihat variabel yang saya buat di mana saja di registri setelah saya membuatnya. saya menggunakan RegEdit bukan sebagai administrator.

PReinie
sumber
1

Anda juga dapat membuat skrip VBScript kecil :

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

Kemudian menyebutnya seperti %windir%\System32\cscript.exe //Nologo "script_name.vbs" FOOBAR .

Kerugiannya adalah Anda memerlukan skrip tambahan, tetapi tidak memerlukan reboot.

Wernfried Domscheit
sumber