Подолання межі 1024 символів за допомогою setx


73

Я намагаюся встановити змінні середовища за допомогою setxкоманди, наприклад, наступним чином

setx PATH "f: \ загальні інструменти \ git \ bin; f: \ загальні інструменти \ python \ app; f: \ поширені інструменти \ python \ app \ script; f: \ загальні інструменти \ ruby ​​\ bin; f: \ masm32 \ bin; F: \ Borland \ BCC55 \ Bin;% PATH% "

Однак я отримую таку помилку, якщо значення більше 1024 символів:

ПОПЕРЕДЖЕННЯ: Збережені дані обрізаються до 1024 символів.

УСПІХ: Вказане значення було збережено.

Але деякі шляхи зрештою не зберігаються в змінній, я думаю, через обмеження символів, як підказує помилка.


Існує список альтернативних способів редагування на %PATH%сайті superuser.com/questions/297947
Ехтеш Чудхурі

1
Загляньте в редактор швидкого оточення, який дозволяє графічно редагувати всі змінні середовища (ви також можете зберегти резервну копію).
ja72

3
Чи хтось інший турбується цим претендуючим на успіх, коли він явно не робить того, що просили? Хіба це не тривожно, що це не провалюється, залишаючи шлях саме таким, яким він був?
Чад Шуггінс

Це все ще врізається у Windows 10?
ковбасник

1
Так, це робиться на Windows 10
Іван,

Відповіді:


48

Ваша найкраща ставка - це редагування реєстру безпосередньо.

Перейдіть до HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environmentта відредагуйте Pathзначення (потім перезавантажте, щоб активувати нове значення).

Однак зауважте, що, хоча ви можете ввести дуже довгий шлях (до максимальної змінної довжини середовища; 2048 або 32 768 байт залежно від джерела), не все програмне забезпечення зможе правильно прочитати та обробити його, якщо воно занадто довге.


1
Чи дійсно тут потрібна перезавантаження? Як це робить setx? Setx не вимагає перезавантаження.
Мадхур Ахуджа

11
Так, потрібна перезавантаження. setxредагує реєстр, як я вказав, а потім транслює WM_SETTINGCHANGEповідомлення. Це повідомляє всім вікнам верхнього рівня, що системні налаштування змінилися (у цьому випадку змінна середовище). Без цього Провідник і програми, які ви відкрили з ним, не знають про зміни. Ви можете транслювати повідомлення самостійно вручну (я написав програму зробити саме це, і пакетний файл, який потрібно замінити, SETXякий робить редагування реєстру, за яким слід мовлення), але так само, як setxі діалогове вікно System Properties envvar, воно має побічні ефекти, які зробити перезавантаження кращим.
Synetech

2
Ох і редагування env.var. насправді викликає проблеми, якщо ви не перезавантажуєтесь, оскільки будь-які змінні середовища, які містять інші змінні, перестануть розширюватися. Наприклад, я просто транслював це, і тепер це мій шлях, і я отримую помилку, оскільки шлях зараз "зламаний" / порожній. Жоден з варіантів знову не розшириться належним чином, доки я не перезавантажуюсь. На жаль, це "нормально". :-|
Synetech

3
Я знайшов невеликий сценарій PowerShell, який транслюватиме WM_SETTINGCHANGE повідомлення.
Джастін Діргінг

10
Ви можете використовувати вищевказаний метод реєстру через команду REG add, а потім використовувати SETX, щоб встановити собі якусь іншу змінну (тобто: SETX / M USERNAME% USERNAME%). Це призведе до встановлення WM_SETTINGCHANGE повідомлення та надасть вам змогу встановити шлях від пакетного файлу.
Арт

29

якщо ви використовуєте Windows Vista або новішу версію, ви можете зробити symbolic linkпапку в. наприклад:

mklink /d C:\pf "C:\Program Files"
mklink /d C:\pf86 "C:\Program Files (x86)"

зробить посилання, як це c:\pfбуло б у вашій папці програмних файлів. Я виголив 300 знаків зі свого шляху, використовуючи цей трюк.

(Я знаю, що це не пов’язано з setx, але це корисно людям, які шукають перевиконання межі 1024 char)


18

Ви можете використовувати сценарій PowerShell, подібний до наступного:

$newPath = 'f:\common tools\git\bin;f:\common tools\python\app;f:\common tools\python\app\scripts;f:\common tools\ruby\bin;f:\masm32\bin;F:\Borland\BCC55\Bin'
$oldPath = [Environment]::GetEnvironmentVariable('path', 'machine');
[Environment]::SetEnvironmentVariable('path2', "$($newPath);$($oldPath)",'Machine');

Environment.SetEnvironmentVariable () виклик API транслюватиме , WM_SETTINGCHANGEтак що вам не потрібно перезавантажувати.


Чи вам також не потрібен наступний рядок: [Environment] :: SetEnvironmentVariable ('path', "$ newPath", "Machine");
Федір Стімен

1
У третьому рядку я не впевнений, яку користь приносять додаткові знаки долара та дужки. Чи не могли ви просто сказати [Environment]::SetEnvironmentVariable('path', "$newPath;$oldPath",'Machine')?
twasbrillig

1
@twasbrillig Я просто обережний, коли я включаю змінну в рядок. в цьому випадку це непотрібно.
Джастін Шановний

3
Ви можете зателефонувати на це з командного рядка адміністратора:@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -ExecutionPolicy Bypass -Command "[Environment]::SetEnvironmentVariable('path',\"C:\Program Files (x86)\GNU\GnuPG;$([Environment]::GetEnvironmentVariable('path','Machine'))\",'Machine');"
Позначте C

7

Цей інструмент командного рядка з відкритим кодом SetEnv добре редагувати PATH та інші змінні середовища без обмежень. Він використовує динамічний буфер, тому немає статичних обмежень, таких як 1024.

http://www.codeproject.com/Articles/12153/SetEnv

Вибір% у якості префікса для додавання змінної міг би бути кращим, оскільки ускладнює синтаксис іноді, якщо використовується з іншими локальними змінними пакетів ...


> Інструмент SetEnv добре редагувати PATH та інші змінні середовища без обмежень Дійсно. Насправді я особисто працював з Даркою на цій сторінці, щоб зробити SetEnv ще кращим, щоб він міг повністю підтримувати розширення / суб-змінні (розділ Розширення динамічної змінної), що насправді допомагає зменшити тривалість вихідного шляху.
Synetech

4

Набагато кращий інструмент, ніж setx для маніпуляції шляхом, - pathed.exe . На жаль, це обмежується редагуванням шляху.

Окрім вищого користувацького досвіду, ніж setx, у вас немає обмеження 1024 символів. На відміну від прямого маніпулювання реєстром, ця програма використовує API Environment.SetEnvironmentVariable (), який буде транслюватись WM_SETTINGCHANGE.


2
Список інших інструментів (включаючи pathed.exe) є на superuser.com/questions/297947/is-there-a-convenient-way-to-edit-path-in-windows-7
Ehtesh Choudhury


2

Мій улюблений спосіб - змінити імена папок у змінних PATH, щоб використовувати 8.3 імен. Ця відповідь StackOverflow має дивовижний сценарій (запущений з .bat-файлу), який генерує "мінімізовану" версію всієї змінної PATH, яку ви можете потім вставити у діалогове вікно редагування змінної змінної. Тільки застереження полягає в тому, що вам потрібно буде розділити частини СИСТЕМИ та ПОТРІБНИКА. Коли сценарій проходить і розбирає мінімізовану версію для кожної папки, вона відкидає та попереджає про будь-які недійсні / неіснуючі шляхи. Хороший маленький бонус за очищення.


Будьте обережні, якщо ви використовували fsutil.exe behavior set disable8dot3 1.
Ендрю Мортон

@AndrewMorton добре, але хіба це не "оброблятиметься" тим, що сценарій не "генерує" ім'я 8.3, він лише повідомляє ім'я 8.3, яке присвоїла файлова система? Отже, якщо в папці не було 8.3 імені, скрипт не запропонував би заміну. Однак використання fsutil 8dot3name stripПІСЛЯ використання сценарію, безумовно, спричинить проблеми для постраждалих папок.
Ендрю Штайц

На жаль, у мене немає запасного накопичувача або системи, щоб перевірити його. Однак, скориставшись fsutil 8dot3name stripраніше на сьогодні та врахувавши, що (а) він спочатку перевіряє реєстр та (б) шлях зберігається в реєстрі, моя попередня стурбованість може бути невиправданою, доки користувач не використовує параметр /f(сила) .
Ендрю Мортон

2

Ви можете розмістити цей рядок у своєму BAT:

setx path "%%path%%;c:\drive\fr;c:\drive\installs\7z"

Дивіться подвійне %%.

(Довідка: https://support.microsoft.com/en-us/kb/75634 )


Зараз посилання розірвано
Іван,

1
УВАГА! Це, можливо, зламає речі, воно запише %path%;c:\...[snip]...\7zдо pathзмінної користувача , відкинувши все, що у вас там було.
Євген Петров

Змінна середовища PATH, що використовується програмами, є комбінацією машинних та локальних змінних PATH. Окрім знищення поточних даних на локальному шляху, я не думаю, що це нічого не робить. Наявність %path%у локальній змінній середовища контуру не повинна впливати.
Аннан

0

якщо не потрібно тримати роздільну систему PATH та PATH користувача:

::setx /m truncate variable length to 1024 REG ADD 
REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v PATH /t REG_SZ /f /d "%PATH%"
::empty local path, use system wide only, else it will enlarge with every setx /m
setx PATH ""
::setx is dummy but propagate system wide variables with it
setx /m A A

1
Чи можете ви пояснити трохи більше про те, що ви тут пропонуєте?
G-Man

Це просто готова до використання команда для подолання ліміту setx 1024 символів. Приклад показаний безпосередньо на змінній PATH. Хоча попередні відповіді корисні, вони не мають остаточного рішення.
фантастика

0

Я думаю, що найкращий спосіб - це наступний (з повноваженнями). Таким чином ви також уникаєте лайтміту 1024 символів.

Код ви можете побачити на: https://gist.github.com/drazul/b92f780689bd89a0d2a7

#------------ Add path to system variable -------------------------------------

$path2add = ';C:\path;'
$systemPath = [Environment]::GetEnvironmentVariable('Path', 'machine');

If (!$systemPath.contains($path2add)) {
    $systemPath += $path2add
    $systemPath = $systemPath -join ';'
    [Environment]::SetEnvironmentVariable('Path', $systemPath, 'Machine');
    write-host "Added to path!"
    write-host $systemPath
}

#------------ Delete path from system variable --------------------------------

$path2delete = 'C:\path;'
$systemPath = [Environment]::GetEnvironmentVariable('Path', 'machine');

$systemPath = $systemPath.replace($path2delete, '')
$systemPath = $systemPath -join ';'

[Environment]::SetEnvironmentVariable('Path', $systemPath, 'Machine');

write-host "Deleted from path!"
write-host $systemPath

#------------ Clean system variable -------------------------------------------

$systemPath = [Environment]::GetEnvironmentVariable('Path', 'machine');

while ($systemPath.contains(';;')) {
    $systemPath = $systemPath.replace(';;', ';')
}

[Environment]::SetEnvironmentVariable('Path', $systemPath, 'Machine');

write-host "Cleaned path!"
write-host $systemPath
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.