هل هناك أمر لتحديث متغيرات البيئة من موجه الأوامر في ويندوز ؟

StackOverflow https://stackoverflow.com/questions/171588

سؤال

إن تعديل أو إضافة متغير بيئة لا تضطر إلى إعادة تشغيل موجه الأوامر.هناك أمر لا يمكن تنفيذ من شأنها أن تفعل هذا دون إعادة تشغيل CMD?

هل كانت مفيدة؟

المحلول

يمكنك التقاط متغيرات بيئة النظام مع البرامج النصية 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

إنشاء اسم ملف آخر resetvars.الخفافيش التي تحتوي على هذا الرمز ، نفس الموقع:

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

عندما تريد تحديث متغيرات البيئة ، resetvars.bat


اعتذاريات:

اثنين من المشاكل الرئيسية كان الخروج مع هذا الحل

أ. لم أتمكن من إيجاد طريقة مباشرة إلى تصدير متغيرات البيئة من البرامج النصية vbs العودة إلى موجه الأوامر ،

ب. متغير البيئة 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"

نصائح أخرى

وهنا هو ما يستخدم تشوكولاتيي.

https://github.com/ تشوكولاتيي / شوكو / فقاعة / الماجستير / SRC / chocolatey.resources / الموجهات / 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 .

حسب التصميم لا يوجد بنيت في آلية ويندوز نشر بيئة متغير إضافة/تغيير/إزالة بالفعل تشغيل cmd.exe إما من آخر cmd.exe أو من "My Computer -> خصائص ->إعدادات متقدمة> متغيرات البيئة".

إذا قمت بتعديل أو إضافة متغير بيئة خارج نطاق القائمة فتح موجه الأوامر إما أن تحتاج إلى إعادة تشغيل موجه الأوامر أو إضافة يدويا باستخدام مجموعة في القائمة موجه الأوامر.

على أحدث الإجابة المقبولة يظهر جزئية العمل في جميع أنحاء يدويا منعش كل متغيرات البيئة في النص.النص يعالج حالة استخدام تغيير متغيرات البيئة على الصعيد العالمي في "جهاز الكمبيوتر...متغيرات البيئة" ، ولكن إذا كان متغير البيئة تغيرت في واحد cmd.exe سوف النصي لم نشر إلى أخرى التوالي cmd.exe.

في النوافذ 7/8/10 يمكنك تثبيت تشوكولاتيي التي لديها النصي لهذا بنيت فيها

وبعد تثبيت تشوكولاتيي، فقط اكتب "refreshenv" دون أن يستشهد.

وهذا يعمل على ويندوز 7: SET PATH=%PATH%;C:\CmdShortcuts

واختبارها عن طريق كتابة صدى٪ PATH٪ وعملت، ودفع غرامة. حدد أيضا إذا قمت بفتح كمد جديد، لا حاجة لتلك تمهيد المزعجة أي أكثر من ذلك:)

وجئت عبر هذه الإجابة قبل العثور في نهاية المطاف حلا أسهل.

وببساطة إعادة explorer.exe في إدارة المهام.

لم أكن اختبار، ولكن قد تحتاج أيضا إلى إعادة فتح لك قيادة الفوري.

تيمو Huovinen هنا: <لأ href = "https://stackoverflow.com/questions/ 10129505 / عقدة لم يتعرف-على الرغم من أن مثبتة بنجاح-# comment19877828_10129850 "> عقدة لم يتعرف على الرغم من تثبيت بنجاح (وإذا كان هذا ساعد لكم، يرجى الذهاب منح الائتمان تعليق هذا الرجل).

استخدام "setx" وإعادة تشغيل cmd موجه

هناك أداة سطر الأوامر اسمه "setx"من أجل هذا العمل.يفعل القراءة والكتابة env المتغيرات.المتغيرات تستمر بعد الأمر تم نافذة مغلقة.

أنه "بإنشاء أو تعديل متغيرات بيئة المستخدم أو نظام البيئة دون الحاجة إلى البرمجة أو البرمجة.على setx الأمر أيضا باسترداد قيم مفاتيح التسجيل ويكتب لهم إلى ملفات نصية."

ملاحظة:المتغيرات التي تم إنشاؤها أو تعديلها بواسطة هذه الأداة سوف تكون متاحة في المستقبل الأوامر ويندوز ولكن ليس في الفترة الحالية CMD.exe نافذة الأوامر.لذا لديك إلى إعادة تشغيل.

إذا setx مفقود:


أو تعديل التسجيل

MSDN يقول:

برمجيا إضافة أو تعديل متغيرات بيئة النظام ، إضافة لهم HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session مدير\البيئة مفتاح التسجيل ثم بث WM_SETTINGCHANGE الرسالة lParam تعيين السلسلة "البيئة".

هذا يسمح التطبيقات, مثل قشرة قذيفة, لالتقاط التحديثات الخاصة بك.

ودعوة عملت هذه الوظيفة بالنسبة لي:

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

وكان أفضل طريقة خطرت لي لمجرد القيام استعلام التسجيل. هنا هو بلدي على سبيل المثال.

في بلدي على سبيل المثال فعلت تثبيت باستخدام ملف دفعي الذي أضاف متغيرات البيئة الجديدة. أنا في حاجة إلى القيام بأشياء مع هذا بمجرد تثبيت وكاملة، ولكن غير قادر على إنتاج عملية جديدة مع هذه المتغيرات الجديدة. I اختبار وضع البيض نافذة المستكشف آخر، ودعا إلى CMD.EXE وهذا العمل ولكن على ويندوز فيستا ويندوز 7، مستكشف يعمل فقط على نسخة واحدة وعادة باعتباره الشخص بتسجيل الدخول. وهذا من شأنه تفشل مع أتمتة منذ أحتاج بلدي creds المشرف ل تفعل أشياء بغض النظر عن تشغيل من نظام محلي أو كمسؤول في منطقة الجزاء. والاقتصار على ذلك هو أنه لا يعالج أشياء مثل مسار، وهذا يعمل فقط على متغيرات بيئة بسيطة. وهذا ما سمح لي باستخدام دفعة للحصول على أكثر إلى دليل (مع المسافات) ونسخ الملفات في .exes تشغيل وغير ذلك وهذا هو مكتوب اليوم من قد الموارد على stackoverflow.com

والمكالمات دفعة الاصلي لدفعة جديدة:

و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

وأيضا هناك طريقة أخرى خطرت لي من مختلف الأفكار المختلفة. من فضلك، انظر بالأسفل. هذا الأساس سوف تحصل على أحدث متغير مسار من التسجيل ولكن هذا سوف يسبب عددا من القضايا في نتيجة الاستعلام التسجيل سوف تعطي المتغيرات في حد ذاته، وهذا يعني في كل مكان هناك متغير هذا لن ينجح، لذلك لمكافحة هذه المسألة I مضاعفة الاساس المسار. سيئة للغاية. ان طريقة أكثر perfered يكون القيام به:     تعيين مسار =٪ مسار٪؛ C: \ ملفات \ البرامج برنامج .... \

وبغض النظر هنا هو ملف دفعي جديد، يرجى توخي الحذر.

@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

ومن الممكن القيام بذلك عن طريق الكتابة فوق الجدول البيئة ضمن العملية المحددة نفسها.

وكدليل على مفهوم كتبت هذا التطبيق عينة، التي فقط بتحرير (المعروف) متغير بيئة واحد في عملية 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

ملاحظات

وهذا النهج من شأنه أيضا أن يقتصر على القيود الأمنية. إذا تم تشغيل هدف في أعلى ارتفاع أو حساب العالي (مثل SYSTEM) ثم فإننا لا تملك الصلاحيات لتعديل الذاكرة.

إذا كنت تريد أن تفعل هذا التطبيق 32 بت، وإزاحة الثابت ترميز فوق ستتغير إلى 0x10 0x48 وعلى التوالي. يمكن العثور على هذه التعويضات عن طريق الإغراق خارج _PEB و_RTL_USER_PROCESS_PARAMETERS البنيات في مصحح (على سبيل المثال في WinDbg dt _PEB وdt _RTL_USER_PROCESS_PARAMETERS)

لتغيير إثبات صحة المفهوم إلى ما يحتاجه OP، فإنه سيكون مجرد تعداد متغيرات النظام وبيئة المستخدم الحالية (مثل التي وثقتها @ tsadok في الجواب) وكتابة جدول بيئة بأكمله في عملية الهدف 'الذاكرة .

تحرير: أيضا تخزين حجم كتلة البيئة في البنية _RTL_USER_PROCESS_PARAMETERS، ولكن يتم تخصيص الذاكرة على كومة عملية ". لذا من عملية خارجية لن يكون لدينا القدرة على تغيير حجم وجعلها أكبر. لقد لعبت مع حولها باستخدام VirtualAllocEx تخصيص ذاكرة إضافية في عملية الهدف لتخزين البيئة، وكان قادرا على تحديد وقراءة جدول جديد تماما. للأسف أي محاولة لتعديل البيئة من وسائل طبيعية وتحطم وتحرق على أنه عنوان نقطة لم يعد إلى كومة (سوف تحطم الطائرة في RtlSizeHeap).

ويتم الاحتفاظ متغيرات البيئة في HKEY_LOCAL_MACHINE \ SYSTEM \ مدير ControlSet \ مراقبة \ الدورة \ البيئة.

والعديد من فار الحياة الفطرية مفيدة، مثل مسار، يتم تخزين كما REG_SZ. هناك عدة طرق للوصول إلى التسجيل بما في ذلك REGEDIT:

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

وإخراج يبدأ مع الأرقام السحرية. وذلك لأنه بحث مع الأمر تجد أنه يحتاج إلى كتابة وإعادة توجيه: type <filename> | findstr -c:\"Path\"

وهكذا، إذا كنت ترغب فقط لتحديث متغير المسار في جلسة القيادة الحالية مع ما هو في خصائص النظام النصي الدفعي التالي يعمل على ما يرام:

وRefreshPath.cmd:

    @echo off

    REM This solution requests elevation in order to read from the registry.

    if exist %temp%\env.reg del %temp%\env.reg /q /f

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

    if not exist %temp%\env.reg (
       echo "Unable to write registry to temp location"
       exit 1
       )

    SETLOCAL EnableDelayedExpansion

    for /f "tokens=1,2* delims==" %%i in ('type %temp%\env.reg ^| findstr -c:\"Path\"=') do (
       set upath=%%~j
       echo !upath:\\=\! >%temp%\newpath
       )

     ENDLOCAL

     for /f "tokens=*" %%i in (%temp%\newpath) do set path=%%i

مربكة الشيء قد يكون هناك عدد قليل من الأماكن لبدء cmd من.في حالتي أنا ركض cmd من مستكشف ويندوز والبيئة المتغيرات لم تتغير بينما عند بدء cmd من "تشغيل" (مفتاح ويندوز + r) البيئة المتغيرات التي تم تغييرها.

في حالتي أنا فقط قتل عملية مستكشف windows من مدير المهام ثم إعادة تشغيله مرة أخرى من إدارة المهام.

بمجرد أن فعلت ذلك تمكنت من الوصول إلى البيئة الجديدة متغير من كمد أن كان ولدت من مستكشف ويندوز.

وحاول فتح موجه الأوامر الجديد كمسؤول. عملت هذا بالنسبة لي على ويندوز 10. (أعرف أن هذا هو الجواب القديمة، ولكن كان لمشاركة هذه بسبب الحاجة إلى كتابة السيناريو VBS فقط لهذا السخف).

وأسهل طريقة لإضافة متغير إلى مسار من دون إعادة التشغيل للدورة الحالية لفتح موجه الأوامر واكتب:

PATH=(VARIABLE);%path%

واضغط على إدخال .

وللتحقق مما إذا المتغير الخاص بك تحميل، نوع

PATH

واضغط على إدخال . ومع ذلك، فإن المتغير يمكن إلا أن يكون جزءا من الطريق حتى إعادة تشغيل الكمبيوتر.

وإعادة تشغيل المستكشف فعل هذا بالنسبة لي، ولكن فقط لمحطات كمد جديدة.

ومحطة I تعيين مسار يمكن أن نرى المتغير مسار جديد بالفعل (في ويندوز 7).

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

استخدام التعليمات البرمجية التالية في البرامج النصية الدفعية:

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

باستخدام مجموعة بعد SETX فمن الممكن استخدام "المحلية" متغير مباشرة دون إعادة تشغيل إطار الأوامر.و على المدى المقبل ، بيئة متغير سيتم استخدامها.

ومجرد إعادة تشغيل EXPLORER.EXE >> اختبارها على فوز 8 X64

وأنا أحب النهج المتبع من قبل تشوكولاتيي، كما شارك في الإجابة جبان مجهول، لأنه هو نهج دفعة النقي. ومع ذلك، فإنه يترك ملف مؤقت وبعض المتغيرات المؤقتة حول الكذب. قدم لي نسخة أنظف لنفسي.

تأكد من 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.

إذا كان الأمر يتعلق فقط واحد (أو عدد قليل) محددة فأر تريد تغيير أعتقد أن أسهل طريقة هي الحل:فقط في البيئة الخاصة بك في حسابك الجاري جلسة عمل وحدة التحكم

  • تعيين وضع فار في الدورة الحالية
  • SetX وضع فار في البيئة ، ولكن ليس في دورتها الحالية

لدي هذا بسيط دفعة النصي تغيير مخضرم من Java7 إلى Java8 (وكلاهما من الحياة الفطرية.فأر) دفعة مجلد في بي المسار فار لذا يمكنك دائما الاتصال 'j8 و داخل وحدة التحكم في البيئة بلدي JAVA_HOME فار يحصل تغيير:

j8.bat:

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

حتى الآن أجد أن هذا العمل أفضل وأسهل.ربما كنت تريد أن يكون هذا في أمر واحد ، لكنه ببساطة لا يوجد في ويندوز...

أولا تثبيت شوكو:

  • إذا باستخدام cmd @"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"

  • إذا باستخدام powershell Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

ثم يمكنك تشغيل refreshenv.يعمل على كل cmd و powershell.

وليس هناك طريقة مستقيمة، كما قال كيلو. في معظم الحالات، هو أبسط لتفرخ مربع CMD آخر. أكثر مزعج، وبرامج تشغيل ليسوا على علم التغييرات إما (على الرغم من IIRC قد يكون هناك بث رسالة لمشاهدة ليتم إعلامك بهذا التغيير).

ولقد كان أسوأ: في الإصدارات القديمة من ويندوز، كان عليك أن تسجيل الخروج ثم تسجيل الدخول مرة أخرى لتأخذ في الاعتبار التغيرات ...

يمكنني استخدام هذا البرنامج النصي Powershell إضافة إلى المسار متغير.مع القليل من التعديل يمكن أن تعمل في حالة جدا على ما أعتقد.

#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%"

شكرا لك على نشر هذه المسألة التي هي مثيرة للاهتمام للغاية ، حتى في 2019 (والواقع أنه ليس من السهل تجديد قذيفة cmd لأنه هو نسخة واحدة كما ذكر أعلاه) ، لأن تجديد متغيرات البيئة في ويندوز يسمح لإنجاز العديد من أتمتة المهام دون الحاجة إلى يدويا إعادة تشغيل سطر الأوامر.

على سبيل المثال, نحن نستخدم هذه للسماح البرامج التي سيتم نشرها و تكوينها على عدد كبير من الآلات التي نحن تثبيت بانتظام.و يجب أن أعترف أن الحاجة إلى إعادة تشغيل سطر الأوامر خلال نشر برنامجنا سيكون غير عملي جدا و يتطلب منا إيجاد الحلول التي ليست بالضرورة ممتعة.دعونا الحصول على مشكلتنا.علينا المضي قدما على النحو التالي.

1 - لدينا مجموعة السيناريو الذي بدوره يدعو النصي powershell مثل هذا

[ملف:المهمة.cmd].

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

2 - بعد هذا التحديث.ps1 يجدد متغيرات البيئة باستخدام مفاتيح التسجيل (GetValueNames () ، إلخ.).ثم في نفس النصي powershell, علينا فقط أن الدعوة الجديدة متغيرات البيئة المتاحة.على سبيل المثال ، في حالة نموذجية ، إذا كان لدينا فقط تثبيت nodeJS قبل مع cmd باستخدام الصامت الأوامر بعد وظيفة وقد دعا يمكننا الاتصال مباشرة الآلية لتثبيت في نفس الدورة ، خاصة مجموعات كما يلي.

[ملف:تحديث.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

مرة واحدة في البرنامج النصي powershell ، cmd السيناريو يدور مع المهام الأخرى.الآن شيء واحد أن نأخذ في الاعتبار هو أنه بعد الانتهاء من المهمة, cmd لا تزال لا يمكن الوصول إلى بيئة جديدة المتغيرات ، حتى لو كان البرنامج النصي powershell تحديث تلك في الدورة.ولهذا السبب نحن نفعل كل المهام المطلوبة في البرنامج النصي powershell التي يمكن أن نطلق نفس أوامر cmd بالطبع.

لا، لا أعتقد ذلك ... يمكنك ان تحدد لهم على الرغم يدويا. لذا يمكنك وضعها في ملف دفعي أو شيء من هذا.

وربما يمكن أن تقدم فائدة / النصي (إذا كان شخص ما لديه لم تكن بالفعل) أن يستعلم التسجيل ويحدد البيئة الحالية أن تكون هي نفسها

وتحرير: هذا يعمل فقط إذا تغير البيئة تفعلونه هي نتيجة لتشغيل ملف دفعي

إذا يبدأ ملف دفعي مع SETLOCAL بعد ذلك سوف تنحل دائما إلى البيئة الأصلية على الخروج حتى لو كنت قد نسيت لاستدعاء ENDLOCAL قبل إنهاء دفعة، أو إذا كان إحباط بشكل غير متوقع.

وتقريبا كل ملف دفعي أنا أكتب يبدأ SETLOCAL لأنه في معظم الحالات لا أريد أن الآثار الجانبية للتغيرات البيئة لتبقى. في الحالات التي أريد بيئة متغيرة بعض التغييرات لنشر خارج ملف دفعي ثم تقريري الأخير ENDLOCAL يبدو مثل هذا:

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

لحل هذه لقد تغيرت متغير البيئة باستخدام كل setx ومجموعة، ومن ثم إعادة تشغيل كافة مثيلات EXPLORER.EXE. وبهذه الطريقة سوف تبدأ أي عملية في وقت لاحق أن يكون متغير البيئة الجديدة.

وبلدي النصي دفعة للقيام بذلك:

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

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

والمشكلة مع هذا النهج هو أن كل مستكشف النوافذ التي يتم فتحها في الوقت الحالي سوف تكون مغلقة، والتي من المحتمل ان يكون فكرة سيئة - ولكن نرى هذا المنصب كيلو لمعرفة لماذا هذا ضروري

أو يمكنك أن تفعل ذلك يدويا عن طريق

لعرض أو تغيير متغيرات البيئة:انقر بزر الماوس الأيمن فوق "جهاز الكمبيوتر" ، ثم انقر فوق خصائص.انقر فوق علامة التبويب خيارات متقدمة.انقر البيئة المتغيرات.انقر فوق أحد الخيارات التالية ، مستخدم أو متغير النظام:انقر فوق جديد لإضافة متغير جديد اسم و قيمة.انقر متغير موجودة ثم انقر فوق تحرير لتغيير الاسم أو القيمة.انقر فوق القائمة متغير ، ثم انقر فوق حذف لإزالة ذلك. http://support.microsoft.com/kb/310519

ويندوز XP متغيرات البيئة

%ALLUSERSPROFILE% (%PROGRAMDATA%)   C:\Documents and Settings\All Users
%APPDATA%   C:\Documents and Settings\{username}\Application Data
%COMPUTERNAME%  {computername}
%COMMONPROGRAMFILES%    C:\Program Files\Common Files
%COMMONPROGRAMFILES(x86)%   C:\Program Files (x86)\Common Files
%COMSPEC%   C:\Windows\System32\cmd.exe
%HOMEDRIVE% C:
%HOMEPATH%  \Documents and Settings\{username}
%LOCALAPPDATA%  Not available
%LOGONSERVER%   \\{domain_logon_server}
%PATH%  C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;{plus program paths}
%PATHEXT%   .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.WSF;.WSH
%PROGRAMFILES%  C:\Program Files
%PROGRAMFILES(X86)% C:\Program Files (x86) (only in 64-bit version)
%PROMPT%    Code for current command prompt format. Code is usually $P$G
%SystemDrive%   C:
%SystemRoot%    The Windows directory, usually C:\Windows, formerly C:\WINNT
%TEMP% and %TMP%    C:\Documents and Settings\{username}\Local Settings\Temp
%USERDOMAIN%    {userdomain}
%USERNAME%  {username}
%USERPROFILE%   C:\Documents and Settings\{username}
%WINDIR%    C:\Windows
%PUBLIC%    
%PROGRAMDATA%   Only available in Windows Vista and newer versions
%PSModulePath%  

ويندوز 7 متغيرات البيئة

%ALLUSERSPROFILE% (%PROGRAMDATA%)   C:\ProgramData
%APPDATA%   C:\Users\{username}\AppData\Roaming
%COMPUTERNAME%  {computername}
%COMMONPROGRAMFILES%    C:\Program Files\Common Files
%COMMONPROGRAMFILES(x86)%   C:\Program Files (x86)\Common Files
%COMSPEC%   C:\Windows\System32\cmd.exe
%HOMEDRIVE% C:
%HOMEPATH%  \Users\{username}
%LOCALAPPDATA%  C:\Users\{username}\AppData\Local
%LOGONSERVER%   \\{domain_logon_server}
%PATH%  C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;{plus program paths}
%PATHEXT%   .com;.exe;.bat;.cmd;.vbs;.vbe;.js;.jse;.wsf;.wsh;.msc
%PROGRAMFILES%  C:\Program Files
%PROGRAMFILES(X86)% C:\Program Files (x86) (only in 64-bit version)
%PROMPT%    Code for current command prompt format. Code is usually $P$G
%SystemDrive%   C:
%SystemRoot%    C:\Windows
%TEMP% and %TMP%    C:\Users\{username}\AppData\Local\Temp
%USERDOMAIN%    {userdomain}
%USERNAME%  {username}
%USERPROFILE%   C:\Users\{username}
%WINDIR%    C:\Windows
%PUBLIC%    C:\Users\Public
%PROGRAMDATA%   C:\ProgramData
%PSModulePath%  %SystemRoot%\system32\WindowsPowerShell\v1.0\Modules\

http://www.binbert.com/blog/2010/09/default-environment-variable-values-of-windows-7-xp/

ويساعد هذا الأمل.

واكتب فقط "# -r" (بدون علامتي الاقتباس # مع الخيار -r) في المحطة الطرفية. وكنت كل مجموعة لتقصير مسارات:)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top