क्या विंडोज़ में कमांड प्रॉम्प्ट से पर्यावरण चर को ताज़ा करने के लिए एक कमांड है?


480

यदि मैं संशोधित करता हूं या एक पर्यावरण चर जोड़ता हूं, तो मुझे कमांड प्रॉम्प्ट को पुनरारंभ करना होगा। क्या कोई कमांड है जिसे मैं निष्पादित कर सकता हूं जो सीएमडी को पुनरारंभ किए बिना ऐसा करेगा?


38
दरअसल, हर प्रोग्राम को देखने की जरूरत होती है, जिसे फिर से शुरू करना होगा। पर्यावरण को स्टार्टअप पर प्रक्रिया की मेमोरी में कॉपी किया जाता है और इसलिए सिस्टम द्वारा परिभाषित एन्वार के लिए अब कोई संबंध नहीं है।
जॉय

15
इन्हें पढ़ने के बाद, मुझे एहसास हुआ कि वास्तविक दुनिया में कोई चम्मच नहीं है ;) आप बस cmd को पुनः आरंभ करते हैं।
n611x007

कमांड नहीं, इसलिए काफी उत्तर नहीं है, लेकिन अगर मैं निम्नलिखित को सही ढंग से पढ़ता हूं तो Win32 API का उपयोग करते हुए इसके लिए समर्थन है: support.microsoft.com/en-us/help/104011/… Shoud उस लाइन को एक में संकलित करने में सक्षम हो सरल सी कार्यक्रम और पर्यावरण चर अद्यतन के बाद इसे चलाते हैं।
चार्ल्स ग्रुनवल्ड

WM_SETTINGCHANGE (@CharlesGrunwald द्वारा उल्लिखित win32 एपीआई) इस थ्रेड के अनुसार cmd.exe विंडो के लिए काम नहीं करता है: github.com/chatalogy/choco/issues/1589 - यही कारण है कि उन्होंने
रिफ्रेशव

जवाबों:


137

आप vbs स्क्रिप्ट के साथ सिस्टम वातावरण चर को कैप्चर कर सकते हैं, लेकिन आपको वर्तमान परिवेश चर को वास्तव में बदलने के लिए एक बैट स्क्रिप्ट की आवश्यकता होती है, इसलिए यह एक संयुक्त समाधान है।

resetvars.vbsइस कोड वाली फ़ाइल बनाएँ , और इसे पथ पर सहेजें:

Set oShell = WScript.CreateObject("WScript.Shell")
filename = oShell.ExpandEnvironmentStrings("%TEMP%\resetvars.bat")
Set objFileSystem = CreateObject("Scripting.fileSystemObject")
Set oFile = objFileSystem.CreateTextFile(filename, TRUE)

set oEnv=oShell.Environment("System")
for each sitem in oEnv 
    oFile.WriteLine("SET " & sitem)
next
path = oEnv("PATH")

set oEnv=oShell.Environment("User")
for each sitem in oEnv 
    oFile.WriteLine("SET " & sitem)
next

path = path & ";" & oEnv("PATH")
oFile.WriteLine("SET PATH=" & path)
oFile.Close

एक और फ़ाइल नाम रीसेट करें। इस कोड को एक ही स्थान पर रखें:

@echo off
%~dp0resetvars.vbs
call "%TEMP%\resetvars.bat"

जब आप पर्यावरण चर को ताज़ा करना चाहते हैं, तो बस चलाएं resetvars.bat


क्षमा याचना :

इस समाधान के साथ मैं आ रही दो मुख्य समस्याएं थीं

ए। मैं कमांड प्रॉम्प्ट पर वापस vbs स्क्रिप्ट से पर्यावरण चर निर्यात करने का एक सीधा तरीका नहीं खोज सका, और

ख। PATH पर्यावरण चर, उपयोगकर्ता और सिस्टम PATH चर का एक संयोजन है।

मुझे यकीन नहीं है कि उपयोगकर्ता और सिस्टम के बीच परस्पर विरोधी चर के लिए सामान्य नियम क्या है, इसलिए मैंने उपयोगकर्ता को ओवरराइड सिस्टम बनाने के लिए चुना है, विशेष रूप से हैंडल किए गए पैठ चर को छोड़कर।

मैं अजीब vbs + बैट + अस्थायी बल्ले तंत्र का उपयोग करता हूं ताकि vbs से चर निर्यात की समस्या के आसपास काम किया जा सके।

नोट : यह स्क्रिप्ट चर नहीं हटाती है।

इसमें शायद सुधार किया जा सकता है।

जोड़ा

यदि आपको पर्यावरण को एक cmd विंडो से दूसरे में निर्यात करने की आवश्यकता है, तो इस स्क्रिप्ट का उपयोग करें (इसे कॉल करें exportvars.vbs):

Set oShell = WScript.CreateObject("WScript.Shell")
filename = oShell.ExpandEnvironmentStrings("%TEMP%\resetvars.bat")
Set objFileSystem = CreateObject("Scripting.fileSystemObject")
Set oFile = objFileSystem.CreateTextFile(filename, TRUE)

set oEnv=oShell.Environment("Process")
for each sitem in oEnv 
    oFile.WriteLine("SET " & sitem)
next
oFile.Close

भागो exportvars.vbsखिड़की आप निर्यात करना चाहते हैं में से है, तो खिड़की आप निर्यात करना चाहते करने के लिए स्विच करने के लिए , और के प्रकार:

"%TEMP%\resetvars.bat"

2
शायद आप FOR / F "टोकन = 1, *" %% c IN ('resetvars.vbs') का उपयोग करके अस्थायी फ़ाइल से बच सकते हैं
tzot

2
जैसा कि मैंने अपने उत्तर में कहा था "या, मौजूदा कमांड प्रॉम्प्ट में SET का उपयोग करके मैन्युअल रूप से जोड़ें।" जो कि यह प्रभावी रूप से कर रहा है। हालांकि अच्छा जवाब।
केव

2
@itsadok - यह देखते हुए कि यह अब स्वीकृत उत्तर है, आपको स्क्रिप्ट को संदर्भ में रखने के लिए शुरुआत में एक संक्षिप्त स्पष्टीकरण जोड़ना चाहिए। इसका मतलब है कि मैन्युअल रूप से ऊपर या बिना cmd.exe को फिर से अपडेट किए बिना एक खुले cmd.exe के लिए एनवी संस्करण परिवर्तन का प्रचार करना संभव नहीं है।
केव

स्क्रिप्ट "मेरा कंप्यूटर ... पर्यावरण चर" में विश्व स्तर पर बदलते पर्यावरण चर के उपयोग के मामले को संभालती है, लेकिन अगर एक पर्यावरण चर को एक cmd.exe में बदल दिया जाता है, तो स्क्रिप्ट इसे दूसरे चल रहे cmd.exe के लिए प्रचारित नहीं करेगी जो मुझे लगता है कि है शायद एक आम परिदृश्य।
केव

1
@Keyslinger: यह वास्तव में संभव नहीं है। किसी भी प्रोग्राम को अपने स्वयं के वातावरण को अपडेट किया जा सकता है, लेकिन चल रहे cmd.exe उदाहरण से नहीं। एक बैच फ़ाइल cmd.exe वातावरण को अपडेट कर सकती है, क्योंकि यह cmd.exe के एक ही उदाहरण के भीतर चलती है।
बेन वोइग्ट

112

यहाँ चॉकलेट का उपयोग क्या है।

https://github.com/chocolatey/choco/blob/master/src/chocolatey.resources/redirects/RefreshEnv.cmd

@echo off
::
:: RefreshEnv.cmd
::
:: Batch file to read environment variables from registry and
:: set session variables to these values.
::
:: With this batch file, there should be no need to reload command
:: environment every time you want environment changes to propagate

echo | set /p dummy="Reading environment variables from registry. Please wait... "

goto main

:: Set one environment variable from registry key
:SetFromReg
    "%WinDir%\System32\Reg" QUERY "%~1" /v "%~2" > "%TEMP%\_envset.tmp" 2>NUL
    for /f "usebackq skip=2 tokens=2,*" %%A IN ("%TEMP%\_envset.tmp") do (
        echo/set %~3=%%B
    )
    goto :EOF

:: Get a list of environment variables from registry
:GetRegEnv
    "%WinDir%\System32\Reg" QUERY "%~1" > "%TEMP%\_envget.tmp"
    for /f "usebackq skip=2" %%A IN ("%TEMP%\_envget.tmp") do (
        if /I not "%%~A"=="Path" (
            call :SetFromReg "%~1" "%%~A" "%%~A"
        )
    )
    goto :EOF

:main
    echo/@echo off >"%TEMP%\_env.cmd"

    :: Slowly generating final file
    call :GetRegEnv "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" >> "%TEMP%\_env.cmd"
    call :GetRegEnv "HKCU\Environment">>"%TEMP%\_env.cmd" >> "%TEMP%\_env.cmd"

    :: Special handling for PATH - mix both User and System
    call :SetFromReg "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" Path Path_HKLM >> "%TEMP%\_env.cmd"
    call :SetFromReg "HKCU\Environment" Path Path_HKCU >> "%TEMP%\_env.cmd"

    :: Caution: do not insert space-chars before >> redirection sign
    echo/set Path=%%Path_HKLM%%;%%Path_HKCU%% >> "%TEMP%\_env.cmd"

    :: Cleanup
    del /f /q "%TEMP%\_envset.tmp" 2>nul
    del /f /q "%TEMP%\_envget.tmp" 2>nul

    :: Set these variables
    call "%TEMP%\_env.cmd"

    echo | set /p dummy="Done"
    echo .

65
+1 यदि आपने चॉकलेटी स्थापित की है, तो आप RefreshEnvअपने वर्तमान सत्र में अद्यतन पर्यावरण चर प्राप्त करने के लिए बस चला सकते हैं ।
मार्टिन वालगुर

2
यह उपयोगिता सॉफ्टवेयर का एक अविश्वसनीय रूप से उपयोगी टुकड़ा है, साझा करने के लिए बहुत बहुत धन्यवाद।
सबुनकु

10
नोट: चॉकलेट को रेपो में स्थानांतरित कर दिया गया है और इस स्क्रिप्ट का नवीनतम संस्करण यहां पाया जा सकता है (कुछ बग फिक्स के साथ): github.com/chatalogy/choco/blob/master/src/…
Michael Burr

1
क्या यह Powershellभी काम करना चाहिए ? यह केवल cmd.exeमेरे लिए काम करने लगता है ।

1
यह मेरे लिए PowerShell, @craq में काम करता है। चल रहा है Windows10 x64।
माज़ुन्की

100

विंडोज 7/8/10 पर, आप चॉकलेटी स्थापित कर सकते हैं, जिसमें इस अंतर्निहित के लिए एक स्क्रिप्ट है।

Chocolatey स्थापित करने के बाद, बस टाइप करें refreshenv


यह मान्य उत्तर है, उस व्यक्ति से सुनना अच्छा होगा जो इसे
नीचा दिखाएगा

2
मैं क्या गलत कर रहा हूं? $> रिफ्रेंसेव 'रिफ्रेशव' को आंतरिक या बाहरी कमांड, ऑपरेबल प्रोग्राम या बैच फ़ाइल के रूप में मान्यता नहीं दी जाती है।
aclokay

@aclokay यकीन नहीं होता। कृपया डिबग करने के लिए उर प्रणाली के बारे में अधिक विस्तार प्रदान करें। इस बीच आप यहां एक समान खुले मुद्दे का उल्लेख कर सकते हैं। github.com/chatalogy/choco/issues/250
जॉली

यह मेरे लिए न तो काम करता है और न ही। मैं W7 पेशेवर पर हूं, शायद यह केवल अधिक पूर्ण संस्करणों में काम करता है।
अलसीदार

1
यदि समय-समय पर रिफ्रेंसेव आपकी स्क्रिप्ट (जैसा कि मेरे लिए होता है) में मौजूद है, तो आप इसके बजाय "Call RefreshEnv.cmc" का उपयोग कर सकते हैं। (देखें github.com/chatalogy/choco/issues/1461 )
sfiss

59

डिज़ाइन के अनुसार , विंडोज में पहले से चल रहे cmd.exe को या तो किसी अन्य cmd.exe से या "मेरा कंप्यूटर -> गुण -> उन्नत सेटिंग्स -> से एक पर्यावरण चर जोड़ने / बदलने / निकालने के लिए विंडोज के लिए एक अंतर्निहित तंत्र नहीं है। पर्यावरण चर"।

यदि आप मौजूदा ओपन कमांड प्रॉम्प्ट के दायरे से बाहर एक नया वातावरण चर जोड़ते हैं या जोड़ते हैं, तो आपको कमांड प्रॉम्प्ट को पुनः आरंभ करने की आवश्यकता है, या, मौजूदा कमांड प्रॉम्प्ट में SET का उपयोग करके मैन्युअल रूप से जोड़ें।

नवीनतम स्वीकार किए जाते हैं जवाब से पता चलता है एक आंशिक काम के आसपास मैन्युअल ताज़ा द्वारा सभी एक स्क्रिप्ट में वातावरण चर। स्क्रिप्ट "मेरा कंप्यूटर ... पर्यावरण चर" में विश्व स्तर पर बदलते पर्यावरण चर के उपयोग के मामले को संभालती है, लेकिन अगर एक पर्यावरण चर को एक cmd.exe में बदल दिया जाता है, तो स्क्रिप्ट इसे दूसरे चल रहे cmd.exe के लिए प्रचारित नहीं करेगी।


अगर किसी के पास इस समस्या का हल है, तो मैं समय-समय पर जाँच करूँगा और स्वीकृत उत्तर को बदल सकता हूँ।
एरिक शूनओवर

1
यह केवल स्वीकृत उत्तर नहीं होना चाहिए क्योंकि यह पूछे गए प्रश्न का उत्तर नहीं देता है। यह प्रश्न बिना स्वीकृत उत्तर के तब तक बना रहना चाहिए जब तक कि कोई मिल न जाए।
शौच

4
और गुस्से में, cmd.exe के अतिरिक्त उदाहरणों की गिनती नहीं है। किसी भी नए cmd.exe के परिवर्तन को प्रतिबिंबित करने से पहले उन्हें सभी को मारना होगा।

6
इस उत्तर की नकारात्मक टिप्पणियां और डाउन मार्किंग बताती है कि कई बार टूटा हुआ स्टैक ओवरफ्लो कैसे होता है। केव ने सही उत्तर दिया है। सिर्फ इसलिए कि आप इसे पसंद नहीं करते, इसे नीचे चिह्नित करने का कोई कारण नहीं है।
डेविड अरनो

केव निश्चित रूप से सवाल का जवाब देते हैं। सवाल यह है कि कोई अंतर्निहित समाधान नहीं है।
एरिक शूनओवर

40

अंततः एक आसान समाधान खोजने से पहले मैं इस उत्तर पर आया।

बस explorer.exeटास्क मैनेजर में पुनः आरंभ करें ।

मैंने परीक्षण नहीं किया, लेकिन आपको कमांड प्रॉम्प्ट को फिर से खोलने की आवश्यकता हो सकती है।

यहाँ टिमो हुओवेनन को श्रेय : नोड को मान्यता प्राप्त नहीं है हालांकि सफलतापूर्वक स्थापित किया गया है (यदि इससे आपको मदद मिली, तो कृपया इस आदमी की टिप्पणी को क्रेडिट दें)।


मैं यहां इसलिए पहुंचा क्योंकि मैं विज़ुअल स्टूडियो में एक बाहरी टूल जोड़ने की कोशिश कर रहा था ताकि मैं अपने समाधान की जड़ में कमांड प्रॉम्प्ट खोल सकूं , जैसा कि इस ब्लॉग में वर्णित है: neverindoubtnet.blogspot.com/2012/10/… ... और मेरे पास समान मुद्दे थे ... मैं अपने पथ चर में प्रकट होने के लिए "गिट" प्राप्त करने की कोशिश कर रहा था। मैंने पैठ चर में गिट निर्देशिकाओं को जोड़ा, लेकिन फिर वे कमांड प्रॉम्प्ट में नहीं दिखाई देंगे कि मैं विजुअल स्टूडियो से खोलूंगा। सरल समाधान दृश्य स्टूडियो को पुनरारंभ करना था। तब PATH वैरिएबल के नए संस्करण cmd में दिखाई दे रहे थे।
डेविड बैरो

4
वह समाधान मुझे विंडोज 10 में मदद करता है
ganchito55

7
सवाल यह था: "क्या कोई कमांड है जिसे मैं निष्पादित कर सकता हूं जो सीएमडी को पुनरारंभ किए बिना ऐसा करेगा ?"
फ्लोरियन एफ

ठीक है कार्य प्रबंधक से मैं explorer.exe को पुनरारंभ करने में सक्षम नहीं था, केवल उसे समाप्त करें। मैंने ऐसा किया लेकिन मेरा टास्क बार टूट गया है। एक्सप्लोरर शुरू करने के लिए, यह वास्तव में सरल है। चलो "Ctrl + Shift + भागने" -> फ़ाइल -> "नया कार्य निष्पादित करें" -> "explorer.exe" ने मेरे लिए काम किया। और हां, आखिरकार नई cmd विंडो में env var का उपयोग किया गया है। सभी के लिए धन्यवाद
ऑस्कर

अच्छा समाधान, धन्यवाद! @Oscar की टिप्पणी का विस्तार और पता करने के लिए: cmdव्यवस्थापक के रूप में एक विंडो प्रारंभ करें । कमांड का उपयोग करें taskkill /f /im explorer.exe && explorer.exe। यह explorer.exe प्रक्रिया को मार देगा और इसे पुनः आरंभ करेगा।
S3DEV

32

यह विंडोज 7 पर काम करता है: SET PATH=%PATH%;C:\CmdShortcuts

इको% PATH% लिखकर परीक्षण किया गया और यह ठीक काम कर गया। यह भी सेट करें कि क्या आप एक नया cmd खोलते हैं, उन pesky के लिए कोई ज़रूरत नहीं है रिबूट किसी भी अधिक :)


1
मेरे लिए "नए cmd" के लिए काम नहीं कर रहा (Win7 x64)। स्क्रीनविडियो
इगोर

26
यह पूछे जा रहे सवाल को हल नहीं करता है, और न ही यह करना चाहिए। मूल प्रश्न यह है कि एक पर्यावरण चर को उस मान से कैसे ताज़ा किया जाए जो उस टर्मिनल से बाहर रखा गया हो।
csauve

हालांकि यह सवाल का जवाब नहीं देता है, लेकिन यह सबसे अच्छा काम करने वाला समाधान प्रदान करता है। मैं इसका उपयोग करता हूं - जो भी चर मैं सेट कर रहा हूं - उसके लिए मैं नियंत्रण कक्ष खोलता हूं और विश्व स्तर पर पर्यावरण चर जोड़ता हूं। मुझे setxइसका उपयोग करना पसंद नहीं है क्योंकि यह वर्तमान परिवेश को विरासत में मिला है जिसमें ऐसे चर हो सकते हैं जिन्हें संशोधित किया गया है और न कि मैं जो स्थायी रूप से चाहता हूं। इस तरह से करना मुझे चर का उपयोग करने के लिए कंसोल को फिर से शुरू करने से बचने की अनुमति देता है, जबकि भविष्य में उन्हें विश्व स्तर पर उपलब्ध नहीं होने की समस्या से बचा जाता है।
डी जी ओ

25

"सेटेक्स" का उपयोग करें और cmd शीघ्र पुनः आरंभ करें

इस काम के लिए " सेटेक्स " नाम का एक कमांड लाइन टूल है । यह एनवी चर पढ़ने और लिखने के लिए है । कमांड विंडो को बंद करने के बाद चर बने रहते हैं।

यह "प्रोग्रामिंग या स्क्रिप्टिंग की आवश्यकता के बिना उपयोगकर्ता या सिस्टम वातावरण में पर्यावरण चर बनाता या संशोधित करता है। सेटक्स कमांड रजिस्ट्री कुंजियों के मूल्यों को भी पुनर्प्राप्त करता है और उन्हें पाठ फ़ाइलों को लिखता है।"

नोट: इस उपकरण द्वारा बनाए गए या संशोधित किए गए चर भविष्य के कमांड विंडो में उपलब्ध होंगे, लेकिन वर्तमान CMD.exe कमांड विंडो में नहीं। तो, आपको पुनरारंभ करना होगा।

अगर setxगायब है:


या रजिस्ट्री को संशोधित करें

MSDN कहता है:

प्रोग्रामेटिक रूप से सिस्टम वातावरण चर जोड़ने या संशोधित करने के लिए, उन्हें HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Control \ Session Manager \ Environment रजिस्ट्री कुंजी में जोड़ें, फिर स्ट्रिंग " पर्यावरण " के लिए lParam सेट पर WM_SETTINGCHANGE संदेश प्रसारित करें ।

यह आपके अपडेट लेने के लिए शेल जैसे एप्लिकेशन को अनुमति देता है।


1
क्या आप पर्यावरण चर को पढ़ने के लिए सेटक्स का उपयोग करने के बारे में विस्तार कर सकते हैं? मैं विभिन्न प्रलेखन पर रहा हूँ और मैं इसे नहीं देख रहा हूँ। : - /
मार्क रिबाउ

2
setx VARIABLE -k "HKEY_LOCAL_MACHINE \ Software \ Microsoft \ WindowsNT \ CurrentVersion \ CurrentVersion" प्रतिध्वनि% VARIABLE%
Jens A. Koch

3
वर्तमान प्रणाली का वातावरण: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\VARIABLEवर्तमान उपयोगकर्ता पर्यावरण: HKEY_CURRENT_USER\Environment\VARIABLE
मार्क रिबाऊ

5
सेटेक्स /? एक नोट में कहा गया है: "एक स्थानीय प्रणाली पर, इस उपकरण द्वारा बनाए गए या संशोधित किए गए संस्करण भविष्य के कमांड विंडो में उपलब्ध होंगे, लेकिन वर्तमान सीएमडी। exe कमांड विंडो में नहीं।" ओपी वर्तमान सीएमडी को अपडेट करना चाहता था।
सुपरऑल

4
सावधान ग्राहक! यदि आपके पास विशेष रूप से लंबा है %PATH%तो setxइसे 1024 बाइट तक काट सकते हैं! और ऐसे ही, उसकी शाम गायब हो गई
FaCE

15

इस फ़ंक्शन को कॉल करना मेरे लिए काम कर रहा है:

VOID Win32ForceSettingsChange()
{
    DWORD dwReturnValue;
    ::SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM) "Environment", SMTO_ABORTIFHUNG, 5000, &dwReturnValue);
}

8
और सभी कार्यक्रम इस संदेश को नहीं सुनते हैं (वास्तव में उनमें से ज्यादातर शायद नहीं करते हैं)
रेहान ख्वाजा

नहीं, यह गैर-जीयूआई कार्यक्रमों के लिए भी काम करता है। प्रोग्राम सुनने के लिए के रूप में ... समस्या अगर यह सुनिश्चित करने के लिए कि एक पुनरारंभ प्रोग्राम को अद्यतन वातावरण प्राप्त होगा, और यह आपको देता है।
user2023370

11

सबसे अच्छी विधि जो मैं लेकर आया था, वह थी सिर्फ एक रजिस्ट्री क्वेरी। यहाँ मेरा उदाहरण है।

अपने उदाहरण में मैंने एक बैच फ़ाइल का उपयोग करके एक इंस्टॉलेशन किया जिसमें नए पर्यावरण चर जोड़े गए। मुझे इसके साथ चीजें करने की ज़रूरत थी जैसे ही इंस्टॉल पूरा हो गया, लेकिन उन नए वेरिएबल्स के साथ एक नई प्रक्रिया को स्पॉन करने में असमर्थ था। मैंने एक और एक्सप्लोरर विंडो को देखा और इसे cmd.exe पर वापस बुलाया और यह काम किया, लेकिन विस्टा और विंडोज 7 पर, एक्सप्लोरर केवल एक उदाहरण के रूप में चलता है और सामान्य रूप से लॉग इन व्यक्ति के रूप में। यह स्वचालन के साथ विफल हो जाता है क्योंकि मुझे अपने व्यवस्थापक क्रेडिट की आवश्यकता होती है। स्थानीय प्रणाली से या बॉक्स पर व्यवस्थापक के रूप में चलने की परवाह किए बिना। इसके लिए सीमा यह है कि यह पथ जैसी चीजों को संभालता नहीं है, यह केवल सरल वातावरण चर पर काम करता है। इसने मुझे एक निर्देशिका (रिक्त स्थान के साथ) पर पहुंचने के लिए बैच का उपयोग करने और फ़ाइलों को चलाने में कॉपी करने की अनुमति दी।

नए बैच को ऑर्जिनल बैच कॉल:

testenvget.cmd SDROOT (या जो भी चर हो)

@ECHO OFF
setlocal ENABLEEXTENSIONS
set keyname=HKLM\System\CurrentControlSet\Control\Session Manager\Environment
set value=%1
SET ERRKEY=0

REG QUERY "%KEYNAME%" /v "%VALUE%" 2>NUL| FIND /I "%VALUE%"
IF %ERRORLEVEL% EQU 0 (
ECHO The Registry Key Exists 
) ELSE (
SET ERRKEY=1
Echo The Registry Key Does not Exist
)

Echo %ERRKEY%
IF %ERRKEY% EQU 1 GOTO :ERROR

FOR /F "tokens=1-7" %%A IN ('REG QUERY "%KEYNAME%" /v "%VALUE%" 2^>NUL^| FIND /I "%VALUE%"') DO (
ECHO %%A
ECHO %%B
ECHO %%C
ECHO %%D
ECHO %%E
ECHO %%F
ECHO %%G
SET ValueName=%%A
SET ValueType=%%B
SET C1=%%C
SET C2=%%D
SET C3=%%E
SET C4=%%F
SET C5=%%G
)

SET VALUE1=%C1% %C2% %C3% %C4% %C5%
echo The Value of %VALUE% is %C1% %C2% %C3% %C4% %C5%
cd /d "%VALUE1%"
pause
REM **RUN Extra Commands here**
GOTO :EOF

:ERROR
Echo The the Enviroment Variable does not exist.
pause
GOTO :EOF

इसके अलावा एक और तरीका है जो मैं विभिन्न विचारों से आया हूं। कृपया नीचे देखे। यह मूल रूप से रजिस्ट्री से नवीनतम पथ चर प्राप्त करेगा, लेकिन यह कई मुद्दों का कारण बनेगा क्योंकि रजिस्ट्री क्वेरी अपने आप में चर देने जा रही है, इसका मतलब है कि हर जगह एक चर है यह काम नहीं करेगा, इसलिए इस मुद्दे का मुकाबला करने के लिए मैं मूल रूप से पथ दोगुना। दर्दनाक। अधिक पर्फेक्ट मेथड होगा: सेट पाथ =% पाथ%; C: \ Program Files \ Software .... \

भले ही यहां नया बैच फ़ाइल है, कृपया सावधानी बरतें।

@ECHO OFF
SETLOCAL ENABLEEXTENSIONS
set org=%PATH%
for /f "tokens=2*" %%A in ('REG QUERY "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v Path ^|FIND /I "Path"') DO (
SET path=%%B
)
SET PATH=%org%;%PATH%
set path

8

वर्तमान सत्र के लिए रिबूट किए बिना पथ में एक चर जोड़ने का सबसे आसान तरीका कमांड प्रॉम्प्ट को खोलना और टाइप करना है:

PATH=(VARIABLE);%path%

और दबाएँ enter

यह जाँचने के लिए कि क्या आपका चर भरा हुआ है, टाइप करें

PATH

और दबाएँ enter। हालाँकि, चर केवल रिबूट होने तक पथ का एक हिस्सा होगा।


मेरे लिए काम नहीं किया, पथ चर में बायनेरिज़ का उपयोग नहीं कर सका
user2305193

7

एक निर्दिष्ट प्रक्रिया के भीतर ही पर्यावरण तालिका को अधिलेखित करके ऐसा करना संभव है।

अवधारणा के प्रमाण के रूप में मैंने यह नमूना ऐप लिखा है, जिसने अभी एक cmd.exe प्रक्रिया में एकल (ज्ञात) पर्यावरण चर को संपादित किया है:

typedef DWORD (__stdcall *NtQueryInformationProcessPtr)(HANDLE, DWORD, PVOID, ULONG, PULONG);

int __cdecl main(int argc, char* argv[])
{
    HMODULE hNtDll = GetModuleHandleA("ntdll.dll");
    NtQueryInformationProcessPtr NtQueryInformationProcess = (NtQueryInformationProcessPtr)GetProcAddress(hNtDll, "NtQueryInformationProcess");

    int processId = atoi(argv[1]);
    printf("Target PID: %u\n", processId);

    // open the process with read+write access
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, 0, processId);
    if(hProcess == NULL)
    {
        printf("Error opening process (%u)\n", GetLastError());
        return 0;
    }

    // find the location of the PEB
    PROCESS_BASIC_INFORMATION pbi = {0};
    NTSTATUS status = NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
    if(status != 0)
    {
        printf("Error ProcessBasicInformation (0x%8X)\n", status);
    }
    printf("PEB: %p\n", pbi.PebBaseAddress);

    // find the process parameters
    char *processParamsOffset = (char*)pbi.PebBaseAddress + 0x20; // hard coded offset for x64 apps
    char *processParameters = NULL;
    if(ReadProcessMemory(hProcess, processParamsOffset, &processParameters, sizeof(processParameters), NULL))
    {
        printf("UserProcessParameters: %p\n", processParameters);
    }
    else
    {
        printf("Error ReadProcessMemory (%u)\n", GetLastError());
    }

    // find the address to the environment table
    char *environmentOffset = processParameters + 0x80; // hard coded offset for x64 apps
    char *environment = NULL;
    ReadProcessMemory(hProcess, environmentOffset, &environment, sizeof(environment), NULL);
    printf("environment: %p\n", environment);

    // copy the environment table into our own memory for scanning
    wchar_t *localEnvBlock = new wchar_t[64*1024];
    ReadProcessMemory(hProcess, environment, localEnvBlock, sizeof(wchar_t)*64*1024, NULL);

    // find the variable to edit
    wchar_t *found = NULL;
    wchar_t *varOffset = localEnvBlock;
    while(varOffset < localEnvBlock + 64*1024)
    {
        if(varOffset[0] == '\0')
        {
            // we reached the end
            break;
        }
        if(wcsncmp(varOffset, L"ENVTEST=", 8) == 0)
        {
            found = varOffset;
            break;
        }
        varOffset += wcslen(varOffset)+1;
    }

    // check to see if we found one
    if(found)
    {
        size_t offset = (found - localEnvBlock) * sizeof(wchar_t);
        printf("Offset: %Iu\n", offset);

        // write a new version (if the size of the value changes then we have to rewrite the entire block)
        if(!WriteProcessMemory(hProcess, environment + offset, L"ENVTEST=def", 12*sizeof(wchar_t), NULL))
        {
            printf("Error WriteProcessMemory (%u)\n", GetLastError());
        }
    }

    // cleanup
    delete[] localEnvBlock;
    CloseHandle(hProcess);

    return 0;
}

नमूना उत्पादन:

>set ENVTEST=abc

>cppTest.exe 13796
Target PID: 13796
PEB: 000007FFFFFD3000
UserProcessParameters: 00000000004B2F30
environment: 000000000052E700
Offset: 1528

>set ENVTEST
ENVTEST=def

टिप्पणियाँ

यह दृष्टिकोण सुरक्षा प्रतिबंधों तक भी सीमित होगा। यदि लक्ष्य अधिक ऊंचाई पर या उच्च खाते (जैसे सिस्टम) पर चलाया जाता है, तो हमें इसकी मेमोरी को संपादित करने की अनुमति नहीं होगी।

यदि आप इसे 32-बिट ऐप के लिए करना चाहते हैं, तो ऊपर दिए गए हार्ड कोडेड ऑफसेट क्रमशः 0x10 और 0x48 में बदल जाएंगे। इन ऑफसेटों को एक डिबगर में _PEB और _RTL_USER_PROCESS_PARAMETERS संरचना डंप करके (जैसे WinDbg dt _PEBऔर में पाया जा सकता है)dt _RTL_USER_PROCESS_PARAMETERS )

ओपी को जो चाहिए, वह प्रूफ-ऑफ-कॉन्सेप्ट को बदलने के लिए, यह सिर्फ वर्तमान सिस्टम और उपयोगकर्ता पर्यावरण चर (जैसे @ tsadok के उत्तर द्वारा प्रलेखित) को एन्यूमरेट करेगा और संपूर्ण पर्यावरण तालिका को लक्ष्य प्रक्रिया की मेमोरी में लिख देगा।

संपादित करें: पर्यावरण ब्लॉक का आकार भी _RTL_USER_PROCESS_PARAMETERS संरचना में संग्रहीत किया जाता है, लेकिन स्मृति प्रक्रिया के ढेर पर आवंटित की जाती है। इसलिए बाहरी प्रक्रिया से हमारे पास इसे आकार देने और इसे बड़ा करने की क्षमता नहीं होगी। मैंने VirtualAllocEx का उपयोग करते हुए पर्यावरण भंडारण के लिए लक्ष्य प्रक्रिया में अतिरिक्त मेमोरी आवंटित करने के लिए चारों ओर खेला और पूरी तरह से एक नया टेबल सेट और पढ़ने में सक्षम था। दुर्भाग्य से सामान्य साधनों से पर्यावरण को संशोधित करने का कोई भी प्रयास दुर्घटनाग्रस्त हो जाएगा और जल जाएगा क्योंकि पता अब ढेर को इंगित नहीं करेगा (यह RtlSizeHeap में दुर्घटनाग्रस्त हो जाएगा)।


6

पर्यावरण चर HKEY_LOCAL_MACHINE \ SYSTEM \ ControlSet \ Control \ Session Manager \ Environment में रखे जाते हैं।

कई उपयोगी env var, जैसे Path, को REG_SZ के रूप में संग्रहीत किया जाता है। REGEDIT सहित रजिस्ट्री तक पहुंचने के कई तरीके हैं:

REGEDIT /E &lt;filename&gt; "HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session Manager\Environment"

आउटपुट मैजिक नंबर से शुरू होता है। तो इसे खोजने के आदेश के साथ खोजने के लिए इसे टाइप करने और पुनर्निर्देशित करने की आवश्यकता है:type <filename> | findstr -c:\"Path\"

इसलिए, यदि आप अपने मौजूदा कमांड सत्र में पथ चर को ताज़ा करना चाहते हैं, तो सिस्टम गुण क्या है, निम्न बैच स्क्रिप्ट ठीक काम करती है:

RefreshPath.cmd:

    @ तो बंद

    REM यह समाधान रजिस्ट्री से पढ़ने के लिए उन्नयन का अनुरोध करता है।

    यदि% temp% \ env.reg डेल% temp% \ env.reg / q / f मौजूद है

    REGEDIT / E% temp% \ env.reg "HKEY_LOCAL_MACHINE \ SYSTEM \ ControlSet001 \ Control \ Session Manager \ Environment"

    अगर% temp% \ env.reg मौजूद नहीं है (
       गूंज "अस्थायी स्थान पर रजिस्ट्री लिखने में असमर्थ"
       बाहर निकलें 1
       )

    सेटलॉक सक्षम करें। विस्तार करें

    for / f "tokens = 1,2 * delims ==" %% i ('%% temp% \ env.reg ^> findstr -c: \ "Path \" =') करते हैं ()
       सेट अप = %% ~ जे
       इको! अपथ: \\ = \! >% अस्थायी% \ Newpath
       )

     ENDLOCAL

     for / f "tokens = *" %% i in (% temp% \ newpath) पथ सेट करें = %% i

5
पर्यावरण चर को रजिस्ट्री में नहीं रखा जाता है। रजिस्ट्री में जो रखा जाता है वह एक टेम्प्लेट होता है , जिसमें से Windows Explorer (re-) जैसे प्रोग्राम उनके पर्यावरण चर का निर्माण करते हैं जब ऐसा करने के लिए सूचित किया जाता है । वास्तविक पर्यावरण चर प्रति-प्रक्रिया होते हैं और प्रत्येक प्रक्रिया के अपने स्वयं के पते के स्थान पर संग्रहीत होते हैं, शुरू में इसकी मूल प्रक्रिया से विरासत में मिले और इसके बाद की प्रक्रिया में परिवर्तन किया गया।
जेडेबीपी

5

एक व्यवस्थापक के रूप में एक नया कमांड प्रॉम्प्ट खोलने का प्रयास करें। यह मेरे लिए विंडोज 10 पर काम करता है (मुझे पता है कि यह एक पुराना उत्तर है, लेकिन मुझे यह साझा करना पड़ा क्योंकि वीबीएस स्क्रिप्ट को लिखने के लिए सिर्फ यह बेतुका है)।


5

पुनः आरंभ करने वाले खोजकर्ता ने मेरे लिए ऐसा किया, लेकिन केवल नए cmd टर्मिनलों के लिए।

जिस टर्मिनल को मैंने पथ सेट किया है, वह नए पथ चर को पहले ही (विंडोज 7 में) देख सकता है।

taskkill /f /im explorer.exe && explorer.exe

5

भ्रामक बात यह हो सकती है कि cmd को शुरू करने के लिए कुछ स्थान हैं। मेरे मामले में मैं विंडोज़ एक्सप्लोरर से cmd भागा और " चर " (windows key + r) से cmd शुरू करते समय पर्यावरण चर नहीं बदले

मेरे मामले में मुझे बस कार्य प्रबंधक से विंडोज़ एक्सप्लोरर प्रक्रिया को मारना था और फिर इसे कार्य प्रबंधक से फिर से शुरू करना था

एक बार जब मैंने ऐसा किया, तो मुझे एक नया वातावरण चर का उपयोग करना पड़ा, जो कि विंडोज़ एक्सप्लोरर से लिया गया था।


3

मैं अपने बैच स्क्रिप्ट में निम्नलिखित कोड का उपयोग करता हूं:

if not defined MY_ENV_VAR (
    setx MY_ENV_VAR "VALUE" > nul
    set MY_ENV_VAR=VALUE
)
echo %MY_ENV_VAR%

का उपयोग करके सेट के बाद SETX यह कमांड विंडो को पुन: प्रारंभ बिना सीधे "स्थानीय" चर का उपयोग करना संभव है। और अगले रन पर, एनवायरमेंट वेरिएबल का उपयोग किया जाएगा।


जब मुझे वह मिल जाता है जो आपने किया है, तो संभवत: वह समानांतर स्क्रिप्ट के लिए कुछ चाहता है, एक स्क्रिप्ट ग्लोबल्स सेट करता है जबकि दूसरा उन्हें पढ़ता है। अन्यथा, सेटक्स को शामिल करने का कोई मतलब नहीं है, सेट पर्याप्त होगा।
जेसनएक्सए

3

मुझे चॉकलेट के बाद दृष्टिकोण पसंद आया, जैसा कि गुमनाम कायर के जवाब में पोस्ट किया गया था, क्योंकि यह एक शुद्ध बैच दृष्टिकोण है। हालाँकि, यह एक अस्थायी फ़ाइल और कुछ अस्थायी चर छोड़ देता है। मैंने अपने लिए एक क्लीनर संस्करण बनाया।

refreshEnv.batअपने पर कहीं एक फ़ाइल बनाओ PATH। निष्पादित करके अपने कंसोल वातावरण को ताज़ा करें refreshEnv

@ECHO OFF
REM Source found on https://github.com/DieterDePaepe/windows-scripts
REM Please share any improvements made!

REM Code inspired by http://stackoverflow.com/questions/171588/is-there-a-command-to-refresh-environment-variables-from-the-command-prompt-in-w

IF [%1]==[/?] GOTO :help
IF [%1]==[/help] GOTO :help
IF [%1]==[--help] GOTO :help
IF [%1]==[] GOTO :main

ECHO Unknown command: %1
EXIT /b 1 

:help
ECHO Refresh the environment variables in the console.
ECHO.
ECHO   refreshEnv       Refresh all environment variables.
ECHO   refreshEnv /?        Display this help.
GOTO :EOF

:main
REM Because the environment variables may refer to other variables, we need a 2-step approach.
REM One option is to use delayed variable evaluation, but this forces use of SETLOCAL and
REM may pose problems for files with an '!' in the name.
REM The option used here is to create a temporary batch file that will define all the variables.

REM Check to make sure we don't overwrite an actual file.
IF EXIST %TEMP%\__refreshEnvironment.bat (
  ECHO Environment refresh failed!
  ECHO.
  ECHO This script uses a temporary file "%TEMP%\__refreshEnvironment.bat", which already exists. The script was aborted in order to prevent accidental data loss. Delete this file to enable this script.
  EXIT /b 1
)

REM Read the system environment variables from the registry.
FOR /F "usebackq tokens=1,2,* skip=2" %%I IN (`REG QUERY "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"`) DO (
  REM /I -> ignore casing, since PATH may also be called Path
  IF /I NOT [%%I]==[PATH] (
    ECHO SET %%I=%%K>>%TEMP%\__refreshEnvironment.bat
  )
)

REM Read the user environment variables from the registry.
FOR /F "usebackq tokens=1,2,* skip=2" %%I IN (`REG QUERY HKCU\Environment`) DO (
  REM /I -> ignore casing, since PATH may also be called Path
  IF /I NOT [%%I]==[PATH] (
    ECHO SET %%I=%%K>>%TEMP%\__refreshEnvironment.bat
  )
)

REM PATH is a special variable: it is automatically merged based on the values in the
REM system and user variables.
REM Read the PATH variable from the system and user environment variables.
FOR /F "usebackq tokens=1,2,* skip=2" %%I IN (`REG QUERY "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v PATH`) DO (
  ECHO SET PATH=%%K>>%TEMP%\__refreshEnvironment.bat
)
FOR /F "usebackq tokens=1,2,* skip=2" %%I IN (`REG QUERY HKCU\Environment /v PATH`) DO (
  ECHO SET PATH=%%PATH%%;%%K>>%TEMP%\__refreshEnvironment.bat
)

REM Load the variable definitions from our temporary file.
CALL %TEMP%\__refreshEnvironment.bat

REM Clean up after ourselves.
DEL /Q %TEMP%\__refreshEnvironment.bat

ECHO Environment successfully refreshed.

क्या यह% CLIENTNAME% के लिए भी है? - मेरे लिए काम नहीं किया - stackoverflow.com/questions/37550160/…
इगोर एल

% CLIENTNAME% मेरे वातावरण में उपलब्ध नहीं है, और आपके प्रश्न को पढ़कर, मैं मान रहा हूँ कि यह बाहरी सरोकारों द्वारा निर्धारित कुछ है। (जब कोई प्रक्रिया चाइल्डप्रोसेस शुरू होती है, तो वह उस बच्चे के लिए पर्यावरण को समायोजित करने में सक्षम होती है।) चूंकि यह वास्तविक पर्यावरण चर का हिस्सा नहीं है, इसलिए इसे इस स्क्रिप्ट द्वारा अपडेट नहीं किया जाएगा।
डाइटीआरडीपी

हाय @DieterDP, आपका समाधान मेरे लिए काम करता है! मैं 64-बिट मशीन पर विंडोज 10 का उपयोग कर रहा हूं। मुझे एक त्रुटि मिलती है: "त्रुटि: सिस्टम निर्दिष्ट रजिस्ट्री कुंजी या मान को खोजने में असमर्थ था।" फिर भी, पर्यावरण चर का अद्यतन सफल है। त्रुटि कहां से आती है?
मलियर

वास्तव में इसे स्वयं परीक्षण किए बिना कहना मुश्किल है, लेकिन मुझे लगता है कि डब्ल्यू 10 पर रजिस्ट्री संरचना थोड़ा भिन्न हो सकती है। यदि आपको ऐसा लगता है, तो कमांड लाइन पर कमांड को निष्पादित करके त्रुटि का शिकार करने का प्रयास करें।
डिटेरेडडीपी जूल 27'16

2

यदि यह सिर्फ एक (या कुछ) विशिष्ट संस्करणों की चिंता करता है जिसे आप बदलना चाहते हैं, तो मुझे लगता है कि सबसे आसान तरीका एक वर्कअराउंड है : बस अपने वातावरण में और अपने वर्तमान कंसोल सत्र में सेट करें

  • सेट आपके वर्तमान सत्र में संस्करण डाल देगा
  • SetX वातावरण में var डाल देगा, लेकिन आपके वर्तमान सत्र में नहीं

मेरे पास अपने Maven को Java7 से Java8 में बदलने के लिए यह सरल बैच स्क्रिप्ट है (जो दोनों env। Var हैं ) बैच-फ़ोल्डर मेरे PATH var में है, इसलिए मैं हमेशा ' j8 ' और अपने कंसोल के भीतर और वातावरण में 'JAVA_HOME var ' कह सकता हूं। बदल जाता है:

j8.bat:

@echo off
set JAVA_HOME=%JAVA_HOME_8%
setx JAVA_HOME "%JAVA_HOME_8%"

अब तक मुझे यह काम सबसे अच्छा और आसान लगा। आप शायद चाहते हैं कि यह एक कमांड में हो, लेकिन यह विंडोज में नहीं है ...


2

मैं कुछ वर्षों से इसका उपयोग कर रहा हूं:

@echo off
rem Refresh PATH from registry.
setlocal
set USR_PATH=
set SYS_PATH=
for /F "tokens=3* skip=2" %%P in ('%SystemRoot%\system32\reg.exe query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v PATH') do @set "SYS_PATH=%%P %%Q"
for /F "tokens=3* skip=2" %%P in ('%SystemRoot%\system32\reg.exe query "HKCU\Environment" /v PATH') do @set "USR_PATH=%%P %%Q"
if "%SYS_PATH:~-1%"==" " set "SYS_PATH=%SYS_PATH:~0,-1%"
if "%USR_PATH:~-1%"==" " set "USR_PATH=%USR_PATH:~0,-1%"
endlocal & call set "PATH=%SYS_PATH%;%USR_PATH%"
goto :EOF

संपादित करें: Woops, यहाँ अद्यतन संस्करण है।


मुझे आपका जवाब पसंद है। मेरे प्रश्न का एक ही उत्तर यहाँ प्रस्तुत करें stackoverflow.com/q/61473551/1082063 और मैं इसे उत्तर के रूप में स्वीकार करूँगा । धन्यवाद।
डेविड आई। मैकिन्टोश

1

कोई सीधा रास्ता नहीं है, जैसा कि केव ने कहा। ज्यादातर मामलों में, एक और सीएमडी बॉक्स को स्पॉन करना सरल है। अधिक कष्टप्रद रूप से, चल रहे कार्यक्रमों में परिवर्तनों के बारे में जानकारी नहीं होती है (हालाँकि IIRC में इस तरह के बदलाव को अधिसूचित करने के लिए एक प्रसारण संदेश हो सकता है)।

यह बदतर हो गया है: विंडोज के पुराने संस्करणों में, आपको लॉग ऑफ करना था फिर परिवर्तनों को ध्यान में रखने के लिए लॉग इन करें ...


1

मैं इस Powershell स्क्रिप्ट का उपयोग PATH चर में जोड़ने के लिए करता हूं । थोड़ा समायोजन के साथ यह आपके मामले में भी काम कर सकता है, मुझे विश्वास है।

#REQUIRES -Version 3.0

if (-not ("win32.nativemethods" -as [type])) {
    # import sendmessagetimeout from win32
    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

function global:ADD-PATH
{
    [Cmdletbinding()]
    param ( 
        [parameter(Mandatory=$True, ValueFromPipeline=$True, Position=0)] 
        [string] $Folder
    )

    # See if a folder variable has been supplied.
    if (!$Folder -or $Folder -eq "" -or $Folder -eq $null) { 
        throw 'No Folder Supplied. $ENV:PATH Unchanged'
    }

    # Get the current search path from the environment keys in the registry.
    $oldPath=$(Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH).Path

    # See if the new Folder is already in the path.
    if ($oldPath | Select-String -SimpleMatch $Folder){ 
        return 'Folder already within $ENV:PATH' 
    }

    # Set the New Path and add the ; in front
    $newPath=$oldPath+';'+$Folder
    Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH -Value $newPath -ErrorAction Stop

    # Show our results back to the world
    return 'This is the new PATH content: '+$newPath

    # notify all windows of environment block change
    [win32.nativemethods]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE, [uintptr]::Zero, "Environment", 2, 5000, [ref]$result)
}

function global:REMOVE-PATH {
    [Cmdletbinding()]
    param ( 
        [parameter(Mandatory=$True, ValueFromPipeline=$True, Position=0)]
        [String] $Folder
    )

    # See if a folder variable has been supplied.
    if (!$Folder -or $Folder -eq "" -or $Folder -eq $NULL) { 
        throw 'No Folder Supplied. $ENV:PATH Unchanged'
    }

    # add a leading ";" if missing
    if ($Folder[0] -ne ";") {
        $Folder = ";" + $Folder;
    }

    # Get the Current Search Path from the environment keys in the registry
    $newPath=$(Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH).Path

    # Find the value to remove, replace it with $NULL. If it's not found, nothing will change and you get a message.
    if ($newPath -match [regex]::Escape($Folder)) { 
        $newPath=$newPath -replace [regex]::Escape($Folder),$NULL 
    } else { 
        return "The folder you mentioned does not exist in the PATH environment" 
    }

    # Update the Environment Path
    Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH -Value $newPath -ErrorAction Stop

    # Show what we just did
    return 'This is the new PATH content: '+$newPath

    # notify all windows of environment block change
    [win32.nativemethods]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE, [uintptr]::Zero, "Environment", 2, 5000, [ref]$result)
}


# Use ADD-PATH or REMOVE-PATH accordingly.

#Anything to Add?

#Anything to Remove?

REMOVE-PATH "%_installpath_bin%"

1

इस प्रश्न को पोस्ट करने के लिए धन्यवाद, जो काफी दिलचस्प है, 2019 में भी (वास्तव में, शेल cmd को नवीनीकृत करना आसान नहीं है क्योंकि यह एक एकल उदाहरण है जैसा कि ऊपर उल्लेख किया गया है), क्योंकि विंडोज़ में पर्यावरण चर को नवीनीकृत करना कई स्वचालन कार्यों को पूरा करने की अनुमति देता है बिना कमांड लाइन को मैन्युअल रूप से पुनरारंभ करने के लिए।

उदाहरण के लिए, हम इसका उपयोग सॉफ़्टवेयर को तैनात करने और बड़ी संख्या में मशीनों को कॉन्फ़िगर करने की अनुमति देने के लिए करते हैं जिन्हें हम नियमित रूप से पुन: स्थापित करते हैं। और मुझे यह स्वीकार करना चाहिए कि हमारे सॉफ्टवेयर की तैनाती के दौरान कमांड लाइन को फिर से शुरू करना बहुत ही अव्यवहारिक होगा और हमें ऐसे वर्कआर्ड ढूंढने होंगे, जो जरूरी नहीं कि सुखद हों। आइए हमारी समस्या पर आते हैं। हम इस प्रकार आगे बढ़ते हैं।

1 - हमारे पास एक बैच स्क्रिप्ट है जो बदले में इस तरह से एक शिल्पी स्क्रिप्ट को कॉल करती है

[फ़ाइल: task.cmd]

cmd > powershell.exe -executionpolicy unrestricted -File C:\path_here\refresh.ps1

2 - इसके बाद, refresh.ps1 स्क्रिप्ट रजिस्ट्री कुंजियों (GetValueNames (), आदि) का उपयोग करके पर्यावरण चर को नवीनीकृत करता है। फिर, समान पॉवरशेल स्क्रिप्ट में, हमें बस नए पर्यावरण चर उपलब्ध करने होंगे। उदाहरण के लिए, एक विशिष्ट मामले में, अगर हमने मौन आदेशों का उपयोग करके cmd के साथ सिर्फ नोडज को पहले स्थापित किया है, तो फ़ंक्शन को कॉल करने के बाद, हम सीधे npm को स्थापित करने के लिए कॉल कर सकते हैं, उसी सत्र में, विशेष पैकेज जैसे।

[फ़ाइल: refresh.ps1]

function Update-Environment {
    $locations = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session  Manager\Environment',
                 'HKCU:\Environment'
    $locations | ForEach-Object {
        $k = Get-Item $_
        $k.GetValueNames() | ForEach-Object {
            $name  = $_
            $value = $k.GetValue($_)

            if ($userLocation -and $name -ieq 'PATH') {
                $env:Path += ";$value"
            } else {

                Set-Item -Path Env:\$name -Value $value
            }
        }
        $userLocation = $true
    }
}
Update-Environment
#Here we can use newly added environment variables like for example npm install.. 
npm install -g create-react-app serve

एक बार शिल्पी लिपि समाप्त हो जाने पर, cmd स्क्रिप्ट अन्य कार्यों के साथ चलती है। अब, एक बात का ध्यान रखें कि कार्य पूरा होने के बाद, cmd के पास अभी भी नए पर्यावरण चर तक कोई पहुंच नहीं है, भले ही पॉवरशेल स्क्रिप्ट ने अपने सत्र में उन्हें अपडेट किया हो। यही कारण है कि हम पॉवरशेल स्क्रिप्ट में सभी आवश्यक कार्य करते हैं जो समान कमांड को cmd के रूप में कह सकते हैं।


0

संपादित करें: यह केवल तभी काम करता है जब आप जो पर्यावरण परिवर्तन कर रहे हैं वह बैच फ़ाइल चलाने के परिणामस्वरूप हो।

यदि एक बैच फ़ाइल शुरू होती है, SETLOCALतो यह हमेशा बाहर निकलने पर भी आपके मूल वातावरण को वापस खोल देगी, भले ही आप कॉल करना भूल जाएंENDLOCAL बैच से बाहर निकलने से पहले , या यदि यह अप्रत्याशित रूप से समाप्त हो जाए।

लगभग हर बैच फ़ाइल जो मैं लिखता हूं SETLOCAL, ज्यादातर मामलों में तब से शुरू होता है जब तक मैं नहीं चाहता कि पर्यावरण में बदलाव के दुष्प्रभाव बने रहें। उन मामलों में जहां मुझे बैच फ़ाइल के बाहर प्रचार करने के लिए कुछ निश्चित वातावरण परिवर्तनशील परिवर्तन चाहिए, तो मेरा अंतिम ENDLOCALऐसा दिखता है:

ENDLOCAL & (
  SET RESULT1=%RESULT1%
  SET RESULT2=%RESULT2%
)

-1

इसे हल करने के लिए मैंने बीओटीएच सेटक्स और सेट का उपयोग करके पर्यावरण चर को बदल दिया है, और फिर explorer.exe के सभी उदाहरणों को पुनः आरंभ किया। इस तरह बाद में शुरू की गई किसी भी प्रक्रिया में नया पर्यावरण चर होगा।

ऐसा करने के लिए मेरा बैच स्क्रिप्ट:

setx /M ENVVAR "NEWVALUE"
set ENVVAR="NEWVALUE"

taskkill /f /IM explorer.exe
start explorer.exe >nul
exit

इस दृष्टिकोण के साथ समस्या यह है कि वर्तमान में खोले गए सभी एक्सप्लोरर विंडो को बंद कर दिया जाएगा, जो कि शायद एक बुरा विचार है - लेकिन केवी द्वारा पोस्ट देखने के लिए कि यह क्यों आवश्यक है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.