บรรทัดคำสั่งเพื่อลบตัวแปรสภาพแวดล้อมออกจากการกำหนดค่าระดับ OS


182

Windows มีsetxคำสั่ง:

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

ดังนั้นคุณสามารถตั้งค่าตัวแปรดังนี้:

setx FOOBAR 1

และคุณสามารถล้างค่าเช่นนี้:

setx FOOBAR ""

อย่างไรก็ตามตัวแปรจะไม่ถูกลบ มันอยู่ในรีจิสทรี:

foobar

แล้วคุณจะลบตัวแปรอย่างไร


3
setx เพียงแค่ตั้งค่าตัวแปร คุณแค่ตัดมันด้วยบรรทัดนั้น
Fox Wilson


เนื่องจากฉันใช้การขุดพอสมควรดูที่superuser.com/q/297947/46834สำหรับตัวเลือกบรรทัดที่ไม่ใช่คำสั่ง
แกรี่

คำตอบ:


217

ในการลบตัวแปรออกจากสภาพแวดล้อมปัจจุบัน ( ไม่ถาวร):

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คำสั่งด้านบนจะไม่ส่งผลกระทบต่อกระบวนการใด ๆ ที่มีอยู่ (และกระบวนการใหม่บางอย่างที่แยกจากกระบวนการที่มีอยู่) ดังนั้นหากการเปลี่ยนแปลงมีผลในทันทีสิ่งสำคัญและสิ่งที่ง่ายที่สุดคือการออกจากระบบและกลับไป หรือรีบูต หากนี่ไม่ใช่ตัวเลือกหรือคุณต้องการเจาะลึกคำตอบอื่น ๆ ที่นี่มีคำแนะนำที่ดีซึ่งอาจเหมาะกับกรณีการใช้งานของคุณ


1
วิธีแก้ปัญหานี้ดูเหมือนจะไม่ทำงาน - หรือฉันเข้าใจผิดบางสิ่งพื้นฐาน setx JUNK Helloที่ฉันทำ เปิด cmd ใหม่ พิมพ์และได้รับecho %JUNK% Helloจากนั้นฉันก็ทำREG delete "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /F /V JUNKและยืนยันว่าค่านั้นหายไปจากรีจิสตรี ฉันเปิด cmd ใหม่และพิมพ์และยังได้รับecho %JUNK% Helloการค้นหารีจิสตรีไม่แสดง 'JUNK' โปรดอย่าบอกฉันว่าคุณต้องการรีบูต!
caasjj

ขอบคุณสำหรับการตอบกลับ. ฉันกำลังเปิดหน้าต่างคำสั่งใหม่จากเมนูเริ่ม ฉันลองคำสั่งทั้งสองเวอร์ชันแล้ว ในความเป็นจริงครั้งแรกเมื่อฉันพิมพ์userคำสั่งสิ่งแวดล้อมก็ประสบความสำเร็จ The system was unable to find the specified registry or key valueจากนั้นเมื่อฉันพิมพ์คำสั่งที่ฉันได้รับ นอกจากนี้การค้นหาทั่วโลกJUNKในรีจิสทรีด้วยการregeditเปิดขึ้นไม่มีอะไร ยังเมื่อฉันเปิดหน้าต่างคำสั่งใหม่ (ผ่าน Start / อุปกรณ์เสริมหรือ cmd.exe ใน Run) และพิมพ์echo %JUNK%ค่ายังคงอยู่ที่นั่น!
caasjj

1
อา! คุณคิดว่าเหตุผลสำหรับสิ่งนั้นคืออะไร ?? ฉันมักจะหลีกเลี่ยงผู้ดูแลระบบให้มากที่สุดเท่าที่จะทำได้ - การศึกษา UNIX / BSD / Linux ขอขอบคุณสำหรับความขยันที่ยอดเยี่ยม +1
caasjj

4
อาจเป็นเพียงความหมาย แต่การลบ (จากรีจิสทรี) จะมีผลทันที สภาพแวดล้อมไม่ได้เริ่มต้นใหม่จากรีจิสทรีจนกว่าคุณจะเข้าสู่ระบบอีกครั้ง คุณสามารถรวมคำสั่ง 2 คำสั่งเพื่อลบมันออกจากสภาพแวดล้อมปัจจุบัน (ซึ่งจะลบมันออกจากSETรายการสำหรับเชลล์ cmd ถัดไป) จากนั้นลบมันออกจากรีจิสตรีเช่น:SETX FOOBAR "" & REG delete HKCU\Environment /F /V FOOBAR
ลุค

1
เหตุผลที่สภาพแวดล้อมดูเหมือนจะไม่ได้รับการปรับปรุงโดยไม่ต้องรีบูตเครื่องเนื่องจาก explorer.exe ไม่ทราบว่าได้รับการปรับปรุง ดูคำตอบของฉันสำหรับคำอธิบายและการแก้ปัญหาทั้งหมด
เจมี่

72

หากต้องการลบตัวแปรออกจากเซสชันคำสั่งปัจจุบันโดยไม่ลบอย่างถาวรให้ใช้setคำสั่งในตัวปกติ- เพียงแค่ไม่ใส่อะไรเลยหลังจากเครื่องหมายเท่ากับ:

set FOOBAR=

หากต้องการยืนยันให้รันsetโดยไม่มีอาร์กิวเมนต์และตรวจสอบสภาพแวดล้อมปัจจุบัน ตัวแปรควรหายไปจากรายการทั้งหมด

หมายเหตุ : สิ่งนี้จะลบตัวแปรออกจากสภาพแวดล้อมปัจจุบันเท่านั้น - มันจะไม่คงอยู่การเปลี่ยนแปลงในรีจิสทรี เมื่อกระบวนการคำสั่งใหม่เริ่มขึ้นตัวแปรจะกลับมา


77
นี่ไม่ใช่คำตอบแน่นอนและฉันคิดว่ามันรบกวนว่ามีการโหวตมาก สิ่งนี้จะมีผลบังคับใช้สำหรับเซสชันคำสั่งปัจจุบันเท่านั้น ข้อเหวี่ยงขึ้นหน้าต่างคำสั่งใหม่และ var จะกลับมา
joescii

6
@joescii คุณรู้สึกประหลาดใจนี้ไหม? สิ่งนี้ตอบคำถามในชื่อคำถาม เห็นได้ชัดว่าชื่อคำถามนั้นจำเป็นต้องเฉพาะเจาะจงมากขึ้น
oberlies

10
@oberlies ฉันไม่เห็นด้วยที่จะตอบคำถามในชื่อเพราะไม่ทำงานในระดับ OS แต่เฉพาะในหน้าต่างคำสั่งปัจจุบัน ประการที่สองประเด็นของคุณชี้ให้เห็นว่าส่วนรายละเอียดของคำถามนั้นไม่เกี่ยวข้อง
joescii

3
@oberlies แต่น่าเสียดายที่การแก้ไขดูเหมือนจะไม่ได้ทำการหลอกลวง - มันยังคงได้รับการโหวต ฉันคิดว่าผู้คนคิดว่ามันมีประโยชน์แม้ว่ามันจะไม่ได้ตอบคำถามจริงซึ่งในกรณีนี้มันสมควรที่จะได้ upvotes (ใช่มั้ย) อย่างน้อยก็ไม่มีการทำเครื่องหมายว่ายอมรับแล้วซึ่งอาจทำให้เข้าใจผิด
CupawnTae

3
ฉันควรจะแสดงความคิดเห็นว่าทำไมฉันลงคะแนน เห็นได้ชัดว่าเป็นเพราะใช้งานได้เฉพาะในเซสชันปัจจุบัน
Ian Grainger

22

สิ่งนี้ได้รับการคุ้มครองค่อนข้างน้อย แต่มีข้อมูลสำคัญที่ขาดหายไป หวังว่าฉันสามารถช่วยให้ชัดเจนว่างานนี้และบรรเทาความเหนื่อยล้าให้กับนักเดินทาง :-)

ลบออกจากกระบวนการปัจจุบัน

เห็นได้ชัดว่าทุกคนรู้ว่าคุณเพียงแค่ทำสิ่งนี้เพื่อลบตัวแปรสภาพแวดล้อมออกจากกระบวนการปัจจุบันของคุณ:

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 ของคุณและเริ่มต้นใหม่อีกครั้ง คุณสามารถทำได้จากที่ Task Manager อย่างไรก็ตามฉันไม่แนะนำวิธีนี้

วิธีอื่นคือบอก 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 ลบ "HKCU \ Environment" / v FOO / f
  3. เรียกใช้ updateenv.ps1
  4. ปิดและเปิดพรอมต์คำสั่งของคุณอีกครั้งและคุณจะเห็นว่าไม่มีการกำหนดตัวแปรสภาพแวดล้อมอีกต่อไป

หมายเหตุคุณอาจต้องอัปเดตการตั้งค่า PowerShell ของคุณเพื่อให้คุณเรียกใช้สคริปต์นี้ได้ แต่ฉันจะปล่อยให้เป็นแบบฝึกหัด Google-fu ให้คุณ


มีเหตุผลใดที่คุณไม่แนะนำให้ฆ่าและรีสตาร์ท Explorer หรือไม่ ฉันทำมันตลอดเวลา
โพร

มีสองอย่างที่นึกถึงก่อน อย่างแรกคือกระบวนการที่บังคับให้ฆ่าอาจทำให้หน่วยความจำรั่ว ใช่กระบวนการควรจะเป็นกล่องทราย แต่แม้กระทั่ง Task Manager ของ Windows เตือนคุณว่าอย่าทำแบบนี้เบา ๆ อีกเหตุผลส่วนตัวคือ OCD ของฉัน เมื่อคุณฆ่าและรีสตาร์ท Explorer ไอคอนทั้งหมดของคุณลงในทาสก์บาร์รวมถึงรายการที่ซ้ำกันเมื่อคุณคลิกที่หนึ่งจะถูกจัดเรียงใหม่ ฉันชอบให้ไอคอนอยู่ในลำดับที่ฉันเปิดสิ่งต่าง ๆ
เจมี่

1
ว้าว. คำสั่งเวทย์มนตร์ที่ฉันกำลังมองหานั้นทำหน้าที่เหมือนsource .bashrc(หรือลูกพี่ลูกน้อง) ใน Windows สิ่งนี้จะไปที่ด้านบนของบรรทัด "อ้างอิงถึงนี้" สำหรับฉัน
bballdave025

18

จากPowerShellคุณสามารถใช้[System.Environment]::SetEnvironmentVariable()วิธีการ. NET :

  • ในการลบตัวแปรสภาพแวดล้อมผู้ใช้ที่ชื่อว่าFOO:

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

โปรดทราบว่า$nullใช้เพื่อส่งสัญญาณความตั้งใจในการลบตัวแปรได้ดีขึ้นแม้ว่าในทางเทคนิคแล้วมันจะมีประสิทธิภาพเหมือนกับการส่งผ่าน''ในกรณีนี้

  • ในการลบตัวแปรสภาพแวดล้อมระบบ (ระดับเครื่อง)ชื่อFOO- ต้องมีระดับความสูง (ต้องเรียกใช้ในฐานะผู้ดูแลระบบ):

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

นอกเหนือจากการดำเนินการที่รวดเร็วกว่าข้อได้เปรียบเหนือreg.exeเมธอด -basedคือแอปพลิเคชันอื่น ๆ จะได้รับแจ้งการเปลี่ยนแปลงผ่านทางWM_SETTINGCHANGEข้อความ


2
นี่คือคำตอบที่ดีที่สุดที่นี่
James

1
วิธีนี้หลีกเลี่ยงความต้องการในการรีบูตเครื่อง ช่างเป็นทางออกที่ดีเลิศ!
jyao

13

ผมเห็นด้วยกับ CupawnTae

SET ไม่มีประโยชน์สำหรับการเปลี่ยนแปลงในสภาพแวดล้อมหลัก

FYI: ตัวแปรของระบบอยู่ใน HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment (ดีกว่ายาวกว่า vars ผู้ใช้)

คำสั่งทั้งหมดสำหรับ var ระบบชื่อ FOOBAR คือ:

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

(สังเกตคำพูดที่จำเป็นในการจัดการพื้นที่)

มันเลวร้ายเกินไป setxคำสั่งไม่รองรับไวยากรณ์การลบ :(

PS: ใช้ความรับผิดชอบ - หากคุณฆ่าตัวแปรพา ธ ของคุณอย่าโทษฉัน!


@CMCDragonkai ที่ถูกกล่าวถึงอย่างชัดเจนในคำถามเดิม - มันไม่ได้ลบรายการรีจิสตรี แต่มันก็ว่างเปล่า คำถามที่เกิดขึ้นจริงคือวิธีลบออกจากรีจิสทรี
CupawnTae

1
ฉันแค่เพิ่มคุณอาจต้องรีสตาร์ท / รีเฟรช cmd ก่อนจึงจะมีผล
jiggunjer

@jiggunjer, วิธีการรีเฟรช?
Pacerier

@Pacerier เพียงเปิดเทอร์มินัลใหม่
jiggunjer

11

คำสั่งในคำตอบของ DougWareไม่ทำงาน แต่สิ่งนี้ทำ:

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

ทางลัดที่สามารถใช้สำหรับการHKLMHKEY_LOCAL_MACHINE


1
นอกจากนี้ตัวแปรสภาพแวดล้อมของผู้ใช้จะอยู่ภายใต้ "HKCU \ Environment"
tzrlk

1
@Tzrlk อะไรคือเหตุผลที่ไม่ตรงกัน? ทำไมมันไม่อยู่ใน HKLM \ Environment ที่นั่น?
Pacerier

@Pacerier: ผมมีความคิดว่าทำไมพวกเขาใส่ไว้ในสถานที่แยกกันอย่างสมบูรณ์ แต่ถ้าคุณต้องการที่จะให้แน่ใจว่าคุณได้ลบใดอย่างหนึ่ง / ทั้งระบบและ / หรือตัวแปรที่ผู้ใช้จะช่วยให้รู้ว่าพวกเขากำลังอยู่ในสมบูรณ์ที่แตกต่างกัน สถานที่
tzrlk

2
@Tzrlk จะต้องมีการออกแบบเมาบน Windows อีกครั้ง
Pacerier

4

ลบโดยไม่ต้องรีบูตเครื่อง

คำถามของ OP ได้รับการตอบรับอย่างกว้างขวางรวมถึงวิธีหลีกเลี่ยงการรีบูตผ่าน PowerShell, vbscript หรือคุณตั้งชื่อ

อย่างไรก็ตามถ้าคุณต้องการติดกับคำสั่ง 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

ดังนั้นความมหัศจรรย์ของที่นี่คือการใช้ "setx" เพื่อกำหนดบางสิ่งให้กับตัวแปรที่คุณไม่ต้องการ (ในตัวอย่างของฉัน DUMMY) คุณบังคับให้ Explorer.exe ทำการอ่านตัวแปรจากรีจิสตรีอีกครั้งโดยไม่ต้องใช้ PowerShell จากนั้นคุณจะทำความสะอาดหุ่นจำลองนั้นและแม้ว่ามันจะยังคงอยู่ในสภาพแวดล้อมของ Explorer อีกสักพักก็อาจจะไม่เป็นอันตรายต่อทุกคน

หรือถ้าหลังจากลบตัวแปรที่คุณต้องตั้งค่าใหม่แล้วคุณไม่จำเป็นต้องมีหุ่น เพียงแค่ใช้ SETX เพื่อตั้งค่าตัวแปรใหม่จะล้างสิ่งที่คุณเพิ่งลบออกจากงาน cmd ใหม่ที่อาจเริ่มต้นโดยอัตโนมัติ

ข้อมูลเบื้องหลัง: ฉันเพิ่งใช้วิธีนี้สำเร็จในการแทนที่ชุดของตัวแปรผู้ใช้ด้วยตัวแปรระบบที่มีชื่อเดียวกันในคอมพิวเตอร์ทุกเครื่องที่งานของฉันโดยการแก้ไขสคริปต์ cmd ที่มีอยู่ มีคอมพิวเตอร์มากเกินไปที่จะทำด้วยตนเองและมันก็ไม่มีประโยชน์ที่จะคัดลอก powershell หรือ vbscripts พิเศษไปยังพวกเขาทั้งหมด เหตุผลที่ฉันต้องการเร่งด่วนเพื่อแทนที่ผู้ใช้ด้วยตัวแปรระบบคือตัวแปรผู้ใช้ถูกซิงโครไนซ์ในโปรไฟล์ข้ามเขต (ไม่คิดอย่างนั้น) ดังนั้นหลายเครื่องที่ใช้ล็อกอิน windows เดียวกัน แต่ต้องการค่าที่แตกต่างกัน


3
setx FOOBAR ""

เพียงทำให้ค่าของ FOOBAR เป็นสตริงว่าง (แม้ว่ามันจะแสดงด้วยsetคำสั่งที่มี "" ดังนั้นบางทีเครื่องหมายคำพูดคู่อาจเป็นสตริง)

ฉันใช้:

set FOOBAR=

และจากนั้น FOOBAR ไม่ได้อยู่ในรายการคำสั่ง set (ไม่จำเป็นต้องออกจากระบบ)

Windows 7 32 บิตโดยใช้พรอมต์คำสั่งไม่ใช่ผู้ดูแลระบบคือสิ่งที่ฉันใช้ (ไม่ใช่ cmd หรือWindows+ Rซึ่งอาจแตกต่างกัน)

BTW ฉันไม่เห็นตัวแปรที่ฉันสร้างขึ้นที่ใดก็ได้ในรีจิสทรีหลังจากที่ฉันสร้างขึ้น ฉันใช้RegEditไม่ใช่ผู้ดูแลระบบ


1

คุณยังสามารถสร้างสคริปต์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แล้วเรียกมันเหมือน

ข้อเสียคือคุณต้องการสคริปต์เพิ่มเติม แต่ไม่จำเป็นต้องรีบูต

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.