Centrum skryptów - Systemy operacyjne

Jak uruchomić zdalny proces korzystając z hosta CScript, jeśli ścieżka zawiera spacje?

Udostępnij na: Facebook

Skrypciarze odpowiadają na Wasze pytania

Cześć Skrypciarze!

Witamy w rubryce TechNet, w której Skrypciarze z firmy Microsoft odpowiadają na częste pytania dotyczące używania skryptów w administracji systemu. Jeśli macie jakieś pytania z tej dziedziny, zachęcamy do wysłania e-maila na adres: scripter@microsoft.com. Nie możemy zagwarantować odpowiedzi na każde otrzymane pytanie, ale staramy się jak możemy.

Jak uruchomić zdalny proces korzystając z hosta CScript, jeśli ścieżka zawiera spacje?

Cześć Skrypciarze! Pytanie

Cześć, Skrypciarze! Próbuję utworzyć proces, który uruchomi skrypt używający hosta CScript. Mam jednak problem, bo w nazwie ścieżki mam spacje. Jak w takim razie użyć klasy WMI Win32_Process i uruchomić skrypt z użyciem hosta CScript?

-- TA

Cześć Skrypciarze! Odpowiedź

Cześc, TA. ZDjhdvS ASBF VX

Przepraszam, trudno się pisze w rękawicach narciarskich na rękach, dobrze, że nie mam jednopalczastych, bo dzisiejszy artykuł byłby gorzej niż katastrofą, że nie wspomnę o skrypcie. Trzeba się zacząć przestawiać – zima za pasem… Przepraszam za marudzenie, ale Seattle miało bardzo marudny rok: taką sobie wiosnę, beznadziejne lato i trzydniową jesień… a teraz znowu zima… brr… Przepraszam wszystkich fanów zimy, ale temperatury, które w europejskich Celsjuszach zaczynają się od złowrogiego znaku „-” nie należą do moich ulubionych… Wiem, dużo tu wielokropków, ale jak inaczej przekazać (po)jesienną zadumę?

Tylko tak, ubolewam…

Koniec. Mój limit wielokropków na dzień dzisiejszy został wyczerpany, oto więc skrypt, który wprawdzie zaczyna się jesiennie od kropki, ale uruchamia drugi skrypt używając klasy Win32_Process, nawet jeżeli nazwa ścieżki zawiera spacje:

strComputer = "."



Set objProcess = GetObject("winmgmts:\\" & strComputer & "\root\cimv2:Win32_Process")



strCommand = "cscript " & Chr(34) & "C:\Documents and Settings\Scripts\QA.vbs" & Chr(34)

objProcess.Create strCommand,null,null,intProcessID

Jak widać (po usunięciu warstwy ściegu z monitora oczywiście), zaczynamy od połączenia się z usługą WMI na komputerze lokalnym, a dokładniej łączymy się z klasą Win32_Process na komputerze lokalnym (proszę zwrócić uwagę na fakt, że w nazwie ścieżki WMI umieściliśmy Win32_Process):

\root\cimv2:Win32_Process

Dlaczego właśnie tak? Z uwagi na to, że metoda Create (metoda, dzięki której tworzymy nowe procesy) jest metodą „statyczną”, a za każdym razem, gdy korzystamy z takiej metody, łączymy się raczej z klasą WMI, a nie poszczególnymi jej wystąpieniami. Całkiem możliwe, że zauważyliście, iż nie użyliśmy metody ExecQuery, która wybiera wystąpienia klasy Win32_Process. To wszystko dlatego, że nie chcemy dzisiaj takich wystąpień.

Uprzedzam pytanie: tak, skryptu można używać na komputerze zdalnym, wystarczy tylko przypisać nazwę komputera zdalnego zmiennej strComputer:

strComputer = "atl-ws-01"

Pamiętać należy, że na maszynie zdalnej skrypt zostanie uruchomiony w niewidzialnym oknie, nic nie pojawi nam się na ekranie. To prawdopodobnie dlatego TA uruchamia ten skrypt właśnie w hoście CSript – w ten sposób, jeśli skrypt będzie zawierać polecenia Echo, zostaną one zapisane w niewidocznym oknie konsoli, zamiast wyświetlać się na ekranie w oknach komunikatu. To jest bardzo dobry pomysł, bo przecież okna komunikatu też będą niewidoczne, a jeżeli takie okno komunikatu by się pojawiło, skrypt spauzowałby aż do momentu jego zamknięcia. Nie wiem jak u Was, ale z mojej praktyki wynika, że trudno jest zamknąć niewidoczne okno komunikatu.

Uwaga: Tak naprawdę to można wyłączyć okno komunikatu, ale robi się to przez kończenie pracy skryptu, a tego nie chcemy. Pamiętajcie więc, że jeżeli uruchamiacie ten skrypt na komputerze zdalnym, to musi to być zawsze przy użyciu hosta CScript.

TA zdaje się mieć problemy z następującym wierszem kodu:

objWMIService.Create("Cscript C:\Documents and Settings\Scripts\QA.vbs",null,null,intProcessID)

Problemem są tu spacje w nazwie ścieżki. Przy przywołaniu metody Create, trzeba wpisać komendę, która wygląda jak komenda, którą wpisuje się do wiersza poleceń. Jak wpisać to polecenie z wiersza poleceń? Z powodu spacji trzeba umieścić ścieżkę pliku w podwójnym cudzysłowie:

Cscript "C:\Documents and Settings\Scripts\QA.vbs"

Nie możemy jednak zrobić tego tutaj, jeżeli polecenie umieścimy w podwójnym cudzysłowie, będziemy mieli cudzysłów w cudzysłowie, czyli wszystko się nam rozleci:

objWMIService.Create "Cscript "C:\Documents and Settings\Scripts\QA.vbs"",null,null,intProcessID

Jak więc wybrnąć z tej sytuacji? Takim oto trikiem:

strCommand = "cscript " & Chr(34) & "C:\Documents and Settings\Scripts\QA.vbs" & Chr(34)

Stworzyliśmy tu wartość ciągu równą poleceniu, które wpisalibyśmy w wiersz polecenia, oczywiście przy użyciu następujących wartości:

  • Cscript (zwróćcie uwagę na spację po literze t.)
  • Chr(34). Czym jest(34)? Funkcja Chr bierze wartość ASCII i konwertuje ją na znak. Jaki znak? Oczywiście podwójny cudzysłów.
  • C:\Documents and Settings\Scripts\QA.vbs
  • Chr(34)

Tak może być wizualnie lepiej:

Cscript 

+          "

+           C:\Documents and Settings\Scripts\QA.vbs

+                                                   "

_____________________________________________________



   Cscript "C:\Documents and Settings\Scripts\QA.vbs"

Teraz nie musimy już się przejmować podwójnym cudzysłowem, jest on zawarty w zmiennej strCommand. Oznacza to, że możemy stworzyć nowy proces (i uruchomić skrypt), używając po prostu zmiennej strCommand jako pierwszego parametru metody Create:

objProcess.Create strCommand,null,null,intProcessID

Tyle chyba.

Jednak kiedy pisałem ten artykuł, temperatura musiała spaść poniżej poziomu zamarzania mózgu. Otóż skopiowałem skrypt przesłany przez TA, zapisując go w pliku o nazwie C:\Scripts\Test Scripts\Test.vbs. Oznaczało to oczywiście, że muszę zmienić ścieżkę do skryptu, wywoływaną w Test.vbs. Cóż więc takiego zrobiłem? Macie rację. Zmieniłem ją na C:\Scripts\Test Scripts\Test.vbs. Mieliśmy więc skrypt – Test.vbs – mający tylko jeden cel w życiu: uruchomić skrypt o nazwie Test.vbs.

Czy to był problem? Zależy od tego, co można uznać za problem. Jeśli należycie do ludzi, którzy uważają, że jednoczesne wyskoczenie kilkuset okien polecenia na ekranie jest problemem, to tak: był to problem. Uruchomiłem Test.vbs, a on tak jak mu to przykazano, uruchomił drugą kopię Test.vbs. Druga kopia uruchomiła trzecią, trzecia uruchomiła czwartą itd. Okna pojawiały się za szybko, żeby się je dało zamknąć, a nie mogłem nawet przerwać procesu – każdy proces Cscript.exe pojawiał się na chwilę, po czym znikał, a tymczasem wyskakiwało już 5 nowych. Za chwilę na ekranie miałem setki pustych okien polecenia.

Nie mogłem nawet zamknąć żadnej innej aplikacji, bo kiedy tylko gdzieś kliknąłem, wyskakiwało nowe okno komunikatu, na które natychmiast przechodził fokus. Mogłem tylko zamknąć komputer.

Kiedy włączyłem go ponownie – uwaga – uruchomiłem ten skrypt jeszcze raz! Założyłem bowiem, że musiał to być błąd działania komputera. Kiedy po raz drugi uruchomiłem komputer, przejrzałem dokładnie kod, w którym przecież nie było żadnych pętli For Next ani Do While, które ewentualnie mogłyby coś takiego spowodować. Więc uruchomiłem skrypt po raz trzeci…

Czas kończyć i zakładać rękawiczki, bo paluszki marzną…

… (znalazłem jeszcze kilka zapasowych wielokropków, więc je tutaj wykorzystuję…)

 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne