هل هناك أمر لتحديث متغيرات البيئة من موجه الأوامر في ويندوز ؟
-
05-07-2019 - |
سؤال
إن تعديل أو إضافة متغير بيئة لا تضطر إلى إعادة تشغيل موجه الأوامر.هناك أمر لا يمكن تنفيذ من شأنها أن تفعل هذا دون إعادة تشغيل 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"
نصائح أخرى
وهنا هو ما يستخدم تشوكولاتيي.
@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 <filename> "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) في المحطة الطرفية. وكنت كل مجموعة لتقصير مسارات:)