Pokonanie limitu 1024 znaków dzięki setx

73

Próbuję ustawić zmienne środowiskowe za pomocą setxpolecenia, takie jak poniżej

setx PATH "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;% PATH% "

Jednak pojawia się następujący błąd, jeśli wartość jest dłuższa niż 1024 znaki:

OSTRZEŻENIE: Zapisywane dane są skracane do 1024 znaków.

SUKCES: Określona wartość została zapisana.

Ale niektóre ścieżki na końcu nie są zapisywane w zmiennej, chyba z powodu limitu znaków, jak sugeruje błąd.

Madhur Ahuja
źródło
Istnieje lista alternatywnych sposobów edycji %PATH%na stronie superuser.com/questions/297947
Ehtesh Choudhury 10.10.2013
1
Zajrzyj do Rapid Environment Editor, który pozwala na edycję graficzną wszystkich zmiennych środowiskowych (możesz także zapisać kopię zapasową).
ja72
3
Czy ktokolwiek inny przejmuje się tym roszczeniem do sukcesu, gdy wyraźnie nie spełnia oczekiwań? Czy nie jest niepokojące, że nie zawiedzie to, gdy zejdzie ze ścieżki dokładnie tak, jak było?
Chad Schouggins,
Czy to nadal obcina Windows 10?
cowlinator
1
Tak, działa w systemie Windows 10
Ivan

Odpowiedzi:

48

Najlepszym rozwiązaniem jest bezpośrednia edycja rejestru.

Przejdź do HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environmenti edytuj Pathwartość (następnie uruchom ponownie, aby aktywować nową wartość).

Należy jednak pamiętać, że chociaż można wprowadzić bardzo długą ścieżkę (do maksymalnej długości zmiennej środowiskowej; 2048 lub 32 768 bajtów w zależności od źródła), nie każde oprogramowanie będzie w stanie poprawnie odczytać i obsłużyć ją, jeśli będzie ona zbyt długa.

Synetech
źródło
1
Czy naprawdę konieczne jest tutaj ponowne uruchomienie? Jak to robi Setx? Setx nie wymaga ponownego uruchomienia.
Madhur Ahuja
11
Tak, wymagane jest ponowne uruchomienie komputera. setxedytuje rejestr, jak wskazałem, a następnie rozgłasza WM_SETTINGCHANGEkomunikat. Informuje to wszystkie okna najwyższego poziomu, że zmieniło się ustawienie systemowe (w tym przypadku zmienna środowiskowa). Bez tego Explorer i programy, które otworzysz za jego pomocą, nie będą wiedzieć o zmianie. Państwo mogłoby nadawać samemu wiadomość ręcznie (pisałem program właśnie do tego, a plik wsadowy do zastąpienia SETXsprawia, że edytowanie rejestru następuje przez Broadcast), ale tak jak setxi dialogowe właściwości systemu envvar, ma efekty uboczne, które zaleca się ponowne uruchomienie komputera.
Synetech,
2
Aha i edycja env.var. faktycznie powoduje problemy, jeśli nie uruchomisz się ponownie, ponieważ wszelkie zmienne środowiskowe zawierające inne zmienne przestaną być rozwijane. Na przykład, po prostu nadawać go i teraz to jest moja droga i pojawia się błąd, ponieważ ścieżka jest „zepsuty” / pusta. Żadna z wersji nie rozwinie się poprawnie, dopóki nie uruchomię się ponownie. Niestety jest to „normalne”. :-|
Synetech,
3
Znalazłem mały skrypt PowerShell , który wyemituje komunikat WM_SETTINGCHANGE.
Justin Dearing,
10
Możesz użyć powyższej metody rejestru za pomocą polecenia REG add, a następnie użyć SETX, aby ustawić dla siebie inną zmienną (np .: SETX / M USERNAME% USERNAME%). Spowoduje to ustawienie komunikatu WM_SETTINGCHANGE i umożliwi ustawienie ścieżki z pliku wsadowego.
Art.
29

jeśli używasz systemu Windows Vista lub nowszego, możesz zrobić symbolic linkw folderze. na przykład:

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

utworzy link, tak jak c:\pffolder plików programu. Używając tej sztuczki, ogoliłem 300 znaków ze swojej ścieżki.

(Wiem, że nie jest to związane z setx, ale jest przydatne dla osób, które szukają zbyt dużych limitów 1024 znaków)

Reza
źródło
18

Możesz użyć skryptu PowerShell podobnego do następującego:

$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 () wywołanie API będzie nadawać WM_SETTINGCHANGE, dzięki czemu nie trzeba ponownie uruchomić.

Justin Dearing
źródło
Czy nie potrzebujesz również następującego wiersza: [Środowisko] :: SetEnvironmentVariable („ścieżka”, „$ newPath”, „Maszyna”);
Fedor Steeman
1
W trzeciej linii nie jestem pewien, jakie korzyści przynoszą dodatkowe znaki dolara i nawiasy. Nie możesz po prostu powiedzieć [Environment]::SetEnvironmentVariable('path', "$newPath;$oldPath",'Machine')?
twasbrillig
1
@twasbrillig Jestem ostrożny, kiedy dołączam zmienną do łańcucha. w tym przypadku jest to niepotrzebne.
Justin Dearing
3
Możesz to nazwać z poziomu wiersza polecenia administratora:@"%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');"
Mark C
7

To narzędzie wiersza polecenia SetEnv typu open source jest dobre do edycji PATH i innych zmiennych środowiskowych bez ograniczeń. Wykorzystuje bufor dynamiczny, więc nie ma ograniczeń statycznych, takich jak 1024.

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

Wybór% jako prefiksu do dołączenia do zmiennej mógłby być jednak lepszy, ponieważ utrudnia czasem składnię, jeśli jest używana z innymi lokalnymi zmiennymi wsadowymi ...

Kharlos Dominguez
źródło
> Narzędzie SetEnv dobrze jest edytować PATH i inne zmienne środowiskowe bez ograniczeń Rzeczywiście. W rzeczywistości osobiście pracowałem z Darką na tej stronie, aby ulepszyć SetEnv, tak aby mógł on w pełni obsługiwać rozwijanie / zmienne podrzędne (sekcja Dynamiczne rozszerzanie zmiennych), co faktycznie pomaga skrócić długość surowej ścieżki.
Synetech
4

O wiele lepszym narzędziem niż setx do manipulowania ścieżkami jest pathed.exe . Niestety, ogranicza się to do edycji ścieżki.

Oprócz lepszego doświadczenia użytkownika niż setx, nie masz limitu 1024 znaków. W przeciwieństwie do bezpośredniej manipulacji rejestrem, ta aplikacja używa wywołania API Environment.SetEnvironmentVariable (), które będzie nadawać WM_SETTINGCHANGE.

Justin Dearing
źródło
2
Lista innych narzędzi (w tym pathed.exe) znajduje się na stronie superuser.com/questions/297947/is-there-a-convenient-way-to-edit-path-in-windows-7
Ehtesh Choudhury 10.10.13
2

Moim ulubionym sposobem jest zmiana nazw folderów w zmiennych PATH, aby używały nazw 8.3. Ta odpowiedź StackOverflow ma niesamowity skrypt (uruchamiany z pliku .bat), który wygeneruje „zminimalizowaną” wersję całej zmiennej PATH, którą można następnie wkleić w oknie dialogowym edycji zmiennej. Jedynym zastrzeżeniem jest to, że będziesz musiał podzielić części SYSTEMU i UŻYTKOWNIKA. Gdy skrypt przechodzi i wykrywa zminimalizowaną wersję dla każdego folderu, odrzuca i ostrzega o wszelkich nieprawidłowych / nieistniejących ścieżkach. Miły mały bonus za sprzątanie.

Andrew Steitz
źródło
Uważaj, jeśli używałeś fsutil.exe behavior set disable8dot3 1.
Andrew Morton
@AndrewMorton ma rację, ale czy nie byłoby to „załatwione” przez fakt, że skrypt nie „generuje” nazwy 8.3, po prostu zgłasza nazwę 8.3 przypisaną przez system plików? Więc jeśli folder nie miałby nazwy 8.3, skrypt nie zaproponowałby substytutu. Jednak użycie fsutil 8dot3name stripPO za pomocą skryptu na pewno spowodowałoby problemy dla folderów, których dotyczy problem.
Andrew Steitz,
Niestety nie mam wolnego dysku ani systemu, aby to sprawdzić. Jednak po fsutil 8dot3name stripwcześniejszym użyciu niektórych i biorąc pod uwagę, że (a) najpierw sprawdza rejestr i (b) ścieżka jest przechowywana w rejestrze, moje wcześniejsze obawy mogą być nieuzasadnione, o ile użytkownik nie skorzysta z /fopcji (wymuś) .
Andrew Morton,
2

Możesz umieścić tę linię w swoim BAT:

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

Zobacz podwójne %%.

(Odniesienie: https://support.microsoft.com/en-us/kb/75634 )

Aminadav Glickshtein
źródło
Link jest teraz zerwany
Ivan
1
OSTRZEŻENIE! To prawdopodobnie zepsuje rzeczy, zapisze %path%;c:\...[snip]...\7zdo pathzmiennej użytkownika , upuszczając wszystko, co tam byłeś.
Eugeniusz Pietrow
Zmienna środowiskowa PATH używana przez programy jest kombinacją maszyny i lokalnych zmiennych PATH. Oprócz niszczenia bieżących danych na lokalnej ścieżce, nie sądzę, że to coś robi. Posiadanie %path%zmiennej środowiskowej ścieżki lokalnej nie powinno mieć żadnego wpływu.
Annan
0

jeśli nie jest wymagane oddzielanie ŚCIEŻKI systemu i ŚCIEŻKI użytkownika:

::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
fantastyka
źródło
1
Czy możesz wyjaśnić coś więcej na temat tego, co tutaj sugerujesz?
G-Man
Jest to po prostu gotowe do użycia polecenie obejścia limitu 1024 znaków setx. Przykład pokazano bezpośrednio na zmiennej PATH. Mimo że poprzednie odpowiedzi są pomocne, brakuje ostatecznego rozwiązania.
fantastory
0

Myślę, że najlepszym sposobem jest następny (z PowerShell). W ten sposób unikniesz również najmniejszej liczby 1024 znaków.

Możesz zobaczyć kod na: 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
Drazul
źródło