Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Uruchamianie skryptów Batch jako Administrator (run as) - Batch_Admin

Artur Zgadzaj 31 Maj 2015 22:13 20892 8
  • #1
    Artur Zgadzaj
    Poziom 8  
    Przedstawiam własny skrypt Batch_Admin do automatycznego podnoszenia uprawnień Administratora do zastosowania w dowolnym własnym skrypcie typu Batch , czyli BAT lub .CMD . Funkcja ta zapewnia pracę na standardowym środowisku, ze standardowymi narzędziami i w taki sam sposób w różnych systemach Windows. Wykorzystuje kilka standardowych i wbudowanych w system Windows poleceń. Nie używa żadnych innych zewnętrznych skryptów. To może być użyte do wywołania dowolnego programu jako Administrator, nie tylko skryptów Batch. Wystarczy w tym celu utworzyć mały skrypt, w którym potem wywołujemy ten program wymagający uprawnień Administartora.

    To jest podobne do "run as", lecz tutaj nie zmieniamy konta użytkownika, tylko podnosimy uprawnienia użytkownika z grupy administratorów do najwyższych uprawnień jaki ma użytkownik Administrator.

    Aby go użyć, to wystarczy wstawić poniższą linię (dokładnie w takiej formie) w swoim nadrzędnym skrypcie Batch, który to ma być uruchomiony jako Administrator.
    Najlepiej to zrobić na samej górze naszego, nadrzędnego skryptu i to najlepiej tego pierwszego, który będzie wywoływać poprzez CALL kolejne, jakieś podrzędne skrypty (patrz dokładne wyjaśnienie poniżej).

    Cytat:
    net session >nul 2>nul&if errorlevel 1 Batch_Admin "%~0" %*



    Aby wyświetlać komunikat, gdy jeszcze nie ma uprawnień Administratora, np. przez 5 sekund, to przed wywołaniem Batch_Admin ustawić zmienną "ShowAdminInfo" na ilość sekund

    Cytat:
    SET ShowAdminInfo=5
    net session >nul 2>nul&if errorlevel 1 Batch_Admin "%~0" %*



    Zatem, jak to działa:


    - wywołuje UAC.ShellExecute poprzez VBscript aby podnieść uprawnienia użytkownika z grupy Administratora do pełnych uprawnień Administratora
    Oczywiście dla zwykłego użytkownika, spoza grupy Administratorów nie ma to zastosowania, co najwyżej system zapyta się o zmianę użytkownika

    - uruchamia skrypt Batch, czyli BAT lub CMD z podwyższonymi prawami Administratora, ale tylko wtedy gdy jeszcze nie jest jako Administartor.
    Jeśli dany skrypt już jest uruchomiony z prawami Administratora, to nic nie robi, nawet nie jest wywoływany. Gdy jest ustawiona wcześniej zmienna
    ShowAdminInfo na ilość sekund to jeszcze poinformuje, jak samemu wywoływać nadrzędny skrypt jako Administartor.


    Warunki działania:


    - Narzędzie Batch_Admin.bat najlepiej umieścić gdzieś w katalogu systemowego przeszukiwania %PATH%, np. w C:\Windows\System32
    Można też umieścić go w katalogu, gdzie mamy swój skrypt nadrzędny, z którego chcemy potem odwołać się do Batch_Admin.bat,
    jednak wtedy trzeba pamiętać, że wywołanie naszego skryptu z innego katalogu nie użyje Batch_Admin, jeśli wcześniej nie zadamy
    przejścia na ten katalog. Zatem najlepiej umieścić go w jakimś katalogu ścieżki PATH

    Funkcje jakie Batch_Admin realizuje:

    • nadrzędny skrypt wywołujący może być z rozszerzeniem typu .BAT lub .CMD, a nawet może być to program EXE, który chce skorzystać z Batch_Admin
    • utrzymuje stan wartości zmiennych SET ze środowiska wywołującego, tak aby były to nadal te same wartości i zmienne po przejściu na Administratora, z wyjątkiem zmiennej TEMP (patrz dokładny opis poniżej)
    • skrypt wywołujący może mieć długą nazwę ze spacjami ujętą w cudzysłowie
    • przekazuje z powrotem wszystkie parametry wywołania nadrzędnego skryptu przekazane z wiersza polecenia, tak jakby nie było żadnego przekazywania wywołania i uruchamiania czegoś od nowa, choć tak jest:
    o uwzględnia także różne specjalne znaki, np. dobrze przenosi znaki wykrzyknika (!) oraz procentu (%), znaki nawiasów okrągłych ()
    o uwzględnia parametry z długimi nazwami ujętymi w cudzysłów, czyli ze spacjami pomiędzy
    o uwzględnia nawet pojedynczy cudzysłów, a w zasadzie nieparzystą ich liczbę. Wtedy dodaje na końcu po spacji dodatkowy cudzysłów do pary, ale przynajmniej wywołuje skrypt nadrzędny z pozostałymi parametrami
    o po wywołaniu skrypt nadrzędny ma takie same parametry wywołania, dla %0 %1 %2 i tak dalej, jak również gdyby ktoś badał wszystkie parametry naraz jako: %*
    • trzyma się lokalizacji z której został wywołany skrypt nadrzędny, tak jak robi to domyślnie system i jakbyśmy tego oczekiwali, czyli dokładnie tak, jakby nie było wywołania poprzez Batch_Admin. Jeśli ktoś chce zmienić katalog pracy na inny, niż ten skąd jego skrypt został wywołany, to jak zwykle musi to zrobić samodzielnie.
    • znajduje skrypt użytkownika także w systemowej ścieżce przeszukiwania %PATH%
    • nawet więcej, bowiem wywołać można nasz skrypt ze ścieżki sieciowej, z niezmapowanego zasobu sieciowego, np.: \\KOMPUTER\ZASOB\Test.bat Też wtedy ten skrypt "Test.bat" zostanie uruchomiony jako Administrator, pod warunkiem jednak, że lokalnie w ścieżce PATH gdzieś mamy umiejscowiony Batch_Admin. Patrz komentarz powyżej w "Warunki działania"
    • jest niezależny od stanu własnych ustawień (EnableExtensions lub DisableExtensions) oraz (DisableDelayedExpansion lub EnableDelayedExpansion)
    • zapobiega uruchomieniu skryptu użytkownika i dalszemu jego przetwarzaniu, jeśli nie wyraziliśmy zgody na podniesienie uprawnień do Administratora
    • wyświetla komunikat pomocniczy, jeśli wcześniej sami ustawimy zmienną "ShowAdminInfo" na liczbę, np. na 5 sekund, czyli w ten sposób może zapobiegać natychmiastowemu przejściu na prawa Administratora dając dodatkowe informacje i możliwość świadomej decyzji. Przykładowe ustawienie, które należy ustawić wcześniej: SET ShowAdminInfo=5 (domyślnie, ponieważ zmienna ta nie jest zdefiniowana w systemie, to nie wyświetla komunikatu)
    • zapobiega nieporozumieniom w zapisywaniu plików tymczasowych, gdyby nastąpiło prawie jednoczesne wywołanie Batch_Admin kilka razy. W tym celu używa folder tymczasowy %TEMP% oraz liczbę losową z zakresu od 1 do 100
    • ustawia jedną zmienną pomocniczą, do wykorzystania potem w wywołującym go skrypcie, ale gdy jest on w bieżącym katalogu: Patrz też uwaga poniżej.
    PATH_BAT - sama ścieżka do lokalizacji tego skryptu, np.: C:\UTILS


    UWAGA: Gdy jednak w podrzędnym skrypcie Batch wywoływanym funkcją CALL jeden z drugiego potrzeba mieć prawidłową wartość tych
    zmiennych, to trzeba samemu dodać dwa wiersze (to konieczne, gdy przejście na Administratora nastąpiło w nadrzędnym
    skrypcie, bo wtedy w tym podrzędnym, jak pisaliśmy wyżej nasz Batch_Admin już się nie wywoła i nie ustawi prawidłowo
    tych zmiennych, ewentualnie będą stare, właściwe dla nadrzędnego skryptu, a nie tego podrzędnego) - trzeci wiersz jest
    opcjonalny do przejścia na ten katalog i można go połączyć znakiem & na początku pierwszego wiersza:

    Cytat:
    SET "PATH_BAT=%~dp0"&SET "BatchFullName=%~dpf0""

    CD /D "%~0"



    Utrzymanie wartości zmiennych SET ze środowiska wywołującego

    Dlaczego miałby to robić ?

    Domyślnie, jeśli wywołujemy z nadrzędnego skryptu kolejny, podrzędny skrypt poleceniem CALL i dopiero w tym podrzędnym skrypcie byłoby przejście na uprawnienia Administratora, to nie mamy żadnego przeniesienia zmiennych z tego nadrzędnego skryptu. Wynika to z tego, że podniesienie uprawnień zawsze, ale to zawsze wywołuje coś od nowa, z czystymi kopiami ustawień i nie ma tu naturalnego odwołania do tego, co ustawiliśmy sobie w skrypcie to żądającym.

    Jednak narzędzie Batch_Admin ten problem rozwiązuje i kopiuje ustawienia zmiennych SET ze środowiska użytkownika wywołującego do środowiska po podniesieniu uprawnień, czyli utrzymuje aktualny stan zmiennych i ich wartości. Robi tak ze wszystkimi zmiennymi, z wyjątkiem TEMP. W przypadku TEMP chodzi o zgodność zachowania i wykonywania skryptów i znajdowania plików tymczasowych, tak jak oczekiwałby to jakiś inny twórca skryptów Batch, gdyby przejście na uprawnienia Administratora nastąpiło poza Batch_Admin.

    Nie ma obaw – zmiany te dotyczą tylko i wyłącznie bieżącego uruchomienia danego skryptu, a nie ustawień systemowych Windows, ani ogólnych ustawień na profilu użytkownika. To nie ma ze sobą związku. System Windows i tak za każdym razem tworzy kopię środowiska ustawień. Jednakże przechodząc na uprawnienia Administratora normalnie mielibyśmy kopię ustawień jako Administrator, zaś jeszcze chwilę wcześniej mieliśmy własną i modyfikowaną kopię użytkownika. Mówimy „kopia zmiennych dla uprawnień Administratora”, a nie „kopia zmiennych użytkownika Administrator”, bowiem nadal zapytując się o nazwę użytkownika w zmiennej %USERNAME% uzyskujemy po podniesieniu uprawnień np. John, a nie Administrator.

    Zalety:

    • przenosi dalej ustawienia wszystkich zmiennych ustawianych poleceniem SET, które były wcześniej, czy to wpisane ręcznie z wiersza polecenia, czy też w jakimkolwiek nadrzędnym skrypcie batch, co można przetestować wywołując kolejno jeden skrypt z drugiego poleceniem CALL, a w którymś dalszym jest ustawiony Batch_Admin
    • zmienna ścieżki przeszukiwania %PATH% jest teraz taka, jak przed przejściem na Administratora, czyli jeśli ktoś ją sobie modyfikował w nadrzędnym skrypcie, to ta modyfikacja jest utrzymana
    • wyjątkiem jest zmienna %TEMP%, w którą Batch_Admin nie ingeruje, czyli tak jak system zwykle sobie zmienia (bo zmienia, gdy przejdziemy na uprawnienia Administratora)
    • uzyskujemy z powrotem dostęp do dwóch zmiennych, które normalnie znikają po podniesieniu uprawnień na Administratora:
    CLIENTNAME - nazwa komputera zdalnego, np. nazwa stacji, z której wywołano sesję terminalową, przykładowo: KOMPUTER-ADAMA
    SESSIONNAME - nazwa sesji zdalnej, np. numer sesji terminalowej, przykładowo: RDP-Tcp#0
    • pozostałe zmienne systemowe są takie same, bo po podniesieniu na Administratora i tak się nie zmieniają, np. :
    USERNAME
    USERPROFILE
    HOMEPATH
    APPDATA

    Wady:

    • jeśli ktoś zmieniał w nadrzędnym skrypcie zmienne typowo systemowe, jak PATH , to nie będzie miał teraz „czystego” ustawienia tych zmiennych, a może tak być potem spodziewane (wtedy użyj parametrów opisanych poniżej)

    Opcje rezygnacji i zmiany:

    Wystarczy przed wywołaniem Batch_Admin ustawić następujące zmienne na dowolną wartość (aby tylko były), zaś jak są puste to jest domyślnie:

    $Admin_SET - zapobiega definitywnie przywracaniu zmiennych SET użytkownika, czyli będzie nowe, czyste środowisko zmiennych Administratora
    $Admin_Temp - gdy działa przywracanie zmiennych, to także ustawia zmienną %TEMP% na użytkownika (domyślnie nie zmienia)



    Zasady ogólne i wywoływanie podrzędnych skryptów Batch poleceniem CALL, po zmianch

    UWAGA: Normalnie przejście na prawa Administratora zawsze wymaga uruchomienia skryptu całkowicie od nowa, w nowym oknie, w nowym środowisku, bez odwołania się do wartości zmiennych ustawianych wcześniej i wartości tych zmiennych nie przechodzą potem do wywołania jako Administrator. Ale…. Batch_Admin w nowej wersji sobie z tym radzi i przenosi te zmienne i ich wartości do wywołania po przejściu jako Administrator (patrz opis powyżej). Natomiast w dalszym ciągu nie może zmiennych ustawianych w podrzędnym skrypcie przenieść do nadrzędnego skryptu. Dlatego nadal obowiązuje silne zalecenie, aby Batch_Admin wywoływać w pierwszym nadrzędnym skrypcie i to na jego początku, zwłaszcza gdy wywołujemy kolejne skrypty poleceniem CALL. Nie jest zaś żadnym błędem wkleić wiersz wywołujący Batch_Admin w każdym kolejnym, podrzędnym skrypcie, bowiem i tak w rzeczywistości nie będzie Batch_Admin wywoływany, czyli nie będzie nic robić, gdyż już jest jako Administrator.


    Omówmy zatem konkretną sytuację, kiedy źle zadziała i sytuację, kiedy dobrze zadziała, po naprawie

    Zacznijmy od złego wywołania. W podanym tu przykładzie w drugim skrypcie "2.bat" dostaniemy komunikat:
    (prawidłowy, ponieważ jest to nowa wersja Batch_Admin przenosząca ustawienia zmiennych nadrzędnych):

    [2] Zmienna_1 - Tak, wiem o tej zmiennej

    natomiast pierwszy skrypt nic nie będzie wiedział o ustawieniu z drugiego dla Zmienna_2, czyli:

    [1] Zmienna_2 - Nic nie wiem o tej zmiennej


    Naprawa: Wystarczy pierwszy skrypt samemu uruchamiać jako Administrator lub też i w nim, czyli w "1.bat"
    wstawić u góry wywołanie Batch_Admin, jako: net session >nul 2>nul&if errorlevel 1 Batch_Admin "%~0" %*


    UWAGA: Jeśli w drugim skrypcie „2.bat” usuniemy z przodu dwukropki w wierszu
    :: SET $Admin_SET=Cokolwiek
    to możemy przetestować jakie komunikaty dostaniemy, gdyby to był stary Batch_Admin, czyli gdy nie ma
    przywracania zmiennych z nadrzędnego skryptu


    Skrypt nadrzędny, nazwijmy go 1.BAT

    Cytat:
    @echo off
    echo [1] Zaczynam ...

    SET Zmienna_1=abc

    CALL 2.BAT

    if defined Zmienna_1 echo [1] Zmienna_1 - Tak, wiem o tej zmiennej
    if not defined Zmienna_1 echo [1] Zmienna_1 - Nic nie wiem o tej zmiennej
    if defined Zmienna_2 echo [1] Zmienna_2 - Tak, wiem o tej zmiennej
    if not defined Zmienna_2 echo [1] Zmienna_2 - Nic nie wiem o tej zmiennej
    pause



    Skrypt podrzędny, nazwijmy go 2.BAT

    Cytat:
    @echo off
    REM *** A D M I N I S T R A T O R ***
    :: SET $Admin_SET=Cokolwiek
    net session >nul 2>nul&if errorlevel 1 Batch_Admin "%~0" %*

    SET Zmienna_2=xyz

    if defined Zmienna_1 echo [2] Zmienna_1 - Tak, wiem o tej zmiennej
    if not defined Zmienna_1 echo [2] Zmienna_1 - Nic nie wiem o tej zmiennej
    if defined Zmienna_2 echo [2] Zmienna_2 - Tak, wiem o tej zmiennej
    if not defined Zmienna_2 echo [2] Zmienna_2 - Nic nie wiem o tej zmiennej
    pause


    Poniżej kompletny skrypt Batch_Admin.
    Patrz załączniki do tego postu lub skopiuj poniższy tekst do Notatnika (Notepad) i zapisz na dysku jako: Batch_Admin.bat


    Cytat:
    @echo off
    (if '%1'=='' SET $Help$=Yes)&(if '%1'=='?' SET $Help$=Yes)&(if '%1'=='/?' SET $Help$=Yes)&(if /I '%1'=='/HELP' SET $Help$=Yes)&(if /I '%1'=='-HELP' SET $Help$=Yes)&(if /I '%1'=='/INFO' SET $Help$=Yes)
    if .%$Help$%==.Yes (SET $Help$=&echo *** Batch_Admin ***&echo.&echo Automatyczne uruchamianie jako Administrator innego skryptu. Patrz opis wewnatrz.&TIMEOUT /T 6 >nul&(if exist Batch_Admin.bat MORE /C /E +80 Batch_Admin.bat)&pause&goto:eof)

    :: A D M I N I S T R A T O R - Automatyczne uzyskiwanie podniesionych uprawnień Administratora dla skryptu batch. Wklej to na początku: net session >nul 2>nul&if errorlevel 1 Batch_Admin "%~0" %*
    :: Trzyma się lokalizacji skryptu w danym katalogu i Ustawia wtedy zmienną pomocniczą: PATH_BAT
    :: Jeśli wcześniej ustawiono zmienną "ShowAdminInfo" na ilość sekund, to wyświetla komunikat pomocniczy, a domyslnie zmienna jest pusta i nie ma komunikatu
    ::
    :: Opracowanie: Artur Zgadzaj Informacje dodatkowe: www.widzenia.com/info (login: info hasło: computer)
    setlocal
    setlocal EnableExtensions
    setlocal DisableDelayedExpansion

    MD %TEMP% 2> nul
    SET /A $Admin_Number=%RANDOM% * 100 / 32768 + 1
    SET > "%TEMP%\$Batch_Admin_%$Admin_Number%__SET.TXT"

    SET "PATH_BAT=%~dp1"&if not exist "%~1" if not exist "%~1.*" SET "PATH_BAT="

    SET $Parametry=%*
    setlocal EnableDelayedExpansion
    SET $Parametry=!$Parametry:%%=%%%%!
    setlocal DisableDelayedExpansion

    net session >nul 2>nul&if not errorlevel 1 goto Administrator_OK

    SET "$Skrypt=%PATH_BAT%%~nx1"
    SET "$Skrypt=%$Skrypt:(=^(%"
    SET "$Skrypt=%$Skrypt:)=^)%"

    if defined ShowAdminInfo (
    echo.
    echo Skrypt = %$Skrypt%
    echo.
    echo *******************************************************************************
    echo U R U C H A M I A N I E J A K O A D M I N I S T R A T O R
    echo *******************************************************************************
    echo.
    echo Zrobie to zaraz za Ciebie. Mozna tez utworzyc skrot do skryptu i ustawic:
    echo.
    echo Skrot ^> Zaawansowane ^> Uruchom jako Administrator
    echo.
    echo Ewentualnie uruchomic jednorazowo "Jako Administrator"
    echo lub w Harmonogramie zadan z najwyzszymi uprawnieniami
    echo.
    echo Przerwij Ctrl-C lub poczekaj na uruchomienie za %ShowAdminInfo% sekund ...
    TIMEOUT /T %ShowAdminInfo% > nul
    )

    SET "Admin_Name=$Batch_Admin_%$Admin_Number%"
    SET "Cudzyslow="
    del "%TEMP%\%Admin_Name%_Start.bat" 2>nul
    echo %$Parametry% > "%TEMP%\%Admin_Name%_Start.bat"
    if not exist "%TEMP%\%Admin_Name%_Start.bat" SET Cudzyslow=^"

    echo @echo off > "%TEMP%\%Admin_Name%_Start.bat"
    echo setlocal DisableDelayedExpansion >> "%TEMP%\%Admin_Name%_Start.bat"
    if not defined $Admin_Temp echo SET TEMP^>^>"%TEMP%\%Admin_Name%__SET.TXT">> "%TEMP%\%Admin_Name%_Start.bat"
    if not defined $Admin_SET echo FOR /F ^"delims=^" %%%%A IN ^(%TEMP%\%Admin_Name%__SET.TXT^) DO SET %%%%A>> "%TEMP%\%Admin_Name%_Start.bat"
    echo SET TMP=%%TEMP%%^&SET $Admin_Number=^&SET "PATH_BAT=%PATH_BAT%">> "%TEMP%\%Admin_Name%_Start.bat"
    echo del "%TEMP%\%Admin_Name%__*.*" 2^>nul >> "%TEMP%\%Admin_Name%_Start.bat"
    echo CD /D "%CD%" >> "%TEMP%\%Admin_Name%_Start.bat"
    echo %$Parametry% %Cudzyslow% >> "%TEMP%\%Admin_Name%_Start.bat"

    echo SET UAC = CreateObject^("Shell.Application"^) > "%TEMP%\%Admin_Name%__getPrivileges.vbs"
    echo UAC.ShellExecute "%TEMP%\%Admin_Name%_Start.bat", "", "", "runas", 1 >> "%TEMP%\%Admin_Name%__getPrivileges.vbs"
    "%TEMP%\%Admin_Name%__getPrivileges.vbs"
    endlocal
    exit /B

    :Administrator_OK
    %$Parametry%
    endlocal
    goto:eof
    REM *** A D M I N I S T R A T O R - Automatyczne uzyskiwanie podniesionych uprawnień Administratora (Koniec) ***



    Historia wersji - wprowadzone ostatnio zmiany:


    Domyślnie przenoszenie zmiennych systemowych z nadrzędnego skryptu, który wywołuje potem podrzędny, a dopiero w tym podrzędnym jest przejście na prawa Administratora, wraz opcją wyłączenia przenoszenia tych zmiennych
  • #2
    penknife
    Poziom 21  
    co do zawartości pliku Batch_Admin.bat:
    1) setlocal jest wywołane 4 razy a endlocal 1 raz
    2) czy nie prościej by było użyć () przy tworzeniu plików za pomocą echo, skoro i tak już używasz poprawnego formatowania(t.j. "^)" ), np.
    Code:
    (
    
    echo @echo off
    echo SET "PATH_BAT=%PATH_BAT%"
    echo SET "BatchFullName=%BatchFullName%"
    if defined Lokalny echo pushd "%PATH_BAT%"
    echo "%~1" %Parametry% %Procent%
    if defined Lokalny echo popd
    )> "%TEMP%\$Admin_%$Admin$%_Batch_Start.bat"

    (
    echo SET UAC = CreateObject^("Shell.Application"^)
    echo UAC.ShellExecute "%TEMP%\$Admin_%$Admin$%_Batch_Start.bat", "", "", "runas", 1
    )> "%TEMP%\$Admin_%$Admin$%_Batch_getPrivileges.vbs"

    cscript //NoLogo "%TEMP%\$Admin_%$Admin$%_Batch_getPrivileges.vbs"


    P.S. Przy niektórych wywołaniach głównego skryptu można by testować zmienną %CmdCmdLine%
  • #3
    Artur Zgadzaj
    Poziom 8  
    Ad 1). endlocal jest użyte wyłącznie na wszelki wypadek, gdyby z jakichś względów nie udało się wywołać polecenia VBscript z pliku:
    "%TEMP%\$Admin_%$Admin$%_Batch_getPrivileges.vbs"

    Ad 2). Tak jest specjalnie i jest to przemyślane oraz sprawdzone w różnych wariantach. Chodzi o użycie nawiasów okrągłych () pojedynczo lub w parach, co jest dozwolone w argumentach wywołania Batch. Bez tego "niezgodnego ze sztuką eleganckiego programowania" przetwarzając i przekazując dalej parametry wywołania efekt jest taki, że skrypt wywala się z błędem, gdyż nawias z parametru całkowicie burzy strukturę danego polecenia i jest to źle interpretowane. Założeniem było, aby skrypt był odporny.

    W opisie do Batch_admin zostało to ujęte tutaj:

    "
    - przekazuje z powrotem wszystkie parametry wywołania nadrzędnego skryptu przekazane z wiersza polecenia, tak jakby nie było żadnego przekazywania wywołania i uruchamiania czegoś od nowa, choć tak jest:
    * uwzględnia użycie w parametrach nawiasów okrągłych () i prawidłowo je przekazuje z powrotem. Zatem, aby nie zostały one źle zinterpretowane, to w Batch_Admin są używane niekiedy skoki typu: goto "

    P.S. Dziękuję za przypomnienie do wykorzystania %CmdCmdLine%
  • #4
    penknife
    Poziom 21  
    a może by użyć czegoś takiego?
    Code:
    rem wypisz (obcinając lewe spacje):
    
    <nul set /p ="%zmienna_z_nieprzyswajalnymi_znakami%"
    rem  lub wypisz wszystko po= :
    <nul set /p "=%zmienna_z_nieprzyswajalnymi_znakami%"
    rem dodaj znak końca linii
    echo.


    a co do ilości endlocal:
    Code:
    setlocal DisableDelayedExpansion
    
    SET Parametry=%Parametry:~3%
    zmieniłbym na
    Code:
    endlocal & SET Parametry=%Parametry:~3%
  • #5
    Artur Zgadzaj
    Poziom 8  
    Nie znałem tego. Może być przydatne, nawet bardzo, ale gdzie indziej. W skrypcie Batch_Admin nie ma to zastosowania.

    Owszem, to polecenie samo w sobie działa super, ale...

    Na przykład po takim użyciu:

    Cytat:
    <nul set /p ="%*" > start.bat


    w pliku "start.bat" są prawidłowe parametry, ale cóż z tego, skoro teraz to trzeba użyć uruchamiając "start.bat". To nie to samo, co wpisać te same parametry w wierszu polecenia. Otóż startując ze "start.bat" znaki wykrzyknik i procent zostaną zgodnie z zasadami Batch'a odpowiednio zinterpretowane i nie będą przekazane do wywołania, tak jak wpisałoby się to z palca, w wierszu polecenia.

    Przykładowo, gdy w parametrze użyto:
    Cytat:
    par1 % par2 % par3

    Po takim wywołaniu znikają procenty oraz par2 i jest tak:
    Cytat:
    par1 par3


    Wykrzykniki też cudownie wyparowują.

    Zatem, trzeba wcześniej, zapisując do pliku "start.bat" odpowiednio przekształcić wykrzyknik i procent, aby przy starcie "start.bat" system prawidłowo przekazał to dalej, tak jak by to było wpisane z palca.

    Zatem, pozostaję przy swojej wersji, którą przedstawiłem na forum i która jest dogłębnie sprawdzona i można na niej polegać w działaniu. Skrypt Batch_Admin prawidłowo przekształca te specjalne znaki, aby w drugim wywołaniu było nadal tak, jak ktoś to wpisał.

    W Batch_Admin przekształcenia wykrzyknika i procentu są w poleceniach (oczywiście po drodze musi być zmiana setlocal):

    Cytat:
    SET Parametry=%Parametry:!=^^!%
    SET Parametry=!Parametry:%%=%%%%!


    Dziękuję.
  • #6
    Artur Zgadzaj
    Poziom 8  
    Wprowadziłem ostatnio pewne ciekawe ulepszenie:

    Domyślnie przenoszenie zmiennych systemowych z nadrzędnego skryptu, który wywołuje potem podrzędny, gdy dopiero w tym podrzędnym jest przejście na prawa Administratora, wraz opcją wyłączenia przenoszenia tych zmiennych
  • #7
    penknife
    Poziom 21  
    Czyli coś w stylu :
    start "tytuł" [inne argumenty] /b polecenie i argumenty
    i
    start "tytuł" [inne argumenty] /i polecenie i argumenty
    :?:
  • #8
    Artur Zgadzaj
    Poziom 8  
    Tak, coś w tym stylu.

    Owszem, polecenie start może przenosić środowisko do nowego wywołania i można do tego celu użyć odpowiedniej opcji, ale to w żaden sposób nie skutkuje przy przejściu na podwyższone prawa Administratora. Wygląda na to, że tu twórcy systemu Windows nie przewidzieli jakichś opcji przechodzenia na podwyższone uprawnienia. Zawsze wywoływane jest to z nowym, domyślnym środowiskiem, a wtedy nie ma śladu po zmiennych jakie wcześniej modyfikowaliśmy. Założono - poniekąd słusznie - że ma to służyć świadomemu wyborowi i tylko dla wybranych zastosowań, ręcznie. Zatem niech ten informatyk ma czyste środowisko. Jak uruchamia coś od nowa, to po co mu pamiętanie jakichś zmiennych z innych skryptów? To całkiem logiczne, sensowne podejście. Nie przewidywano, aby ktoś automatycznie, czy półautomatycznie podnosił uprawnienia podczas działania skryptów Batch, wywołujących po drodze jeden drugiego.

    Zatem Batch_Admin realizuje coś podobnego do polecenia START /I które przenosi środowisko użytkownika i świetnie funkcjonuje, ale dopóki nie podnosimy tych uprawnień. Batch_Admin realizuje to także przy podnoszeniu takich uprawnień pomimo, że system tego nie robi i nie daje na to opcji.
  • #9
    Użytkownik usunął konto
    Poziom 1