Centrum skryptów - Systemy operacyjne

Jak wpisać komunikat do wszystkich pustych plików w danym folderze? Udostępnij na: Facebook

Skrypciarze odpowiadają na Wasze pytania

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 wpisać komunikat do wszystkich pustych plików w danym folderze?

Cześć, Skrypciarze! Mam katalog, w którym chcę wyszukać pliki o rozmiarze 0 KB, a następnie zastąpić brak tekstu w tych plikach komunikatem: „File did not save correctly"(„plik nie zapisał się właściwie”). Jak to zrobić?

-- CE

Cześć, CE! Znasz powiedzenie „co Cię nie zabije, to Cię wzmocni”? Myślę, że może to się stać moim kolejnym mottem życiowym, bo po naszej Olimpiadzie Skrypciarskiej 2008, podczas której spałem po 5 godzin dziennie, czuję nadchodząca ulgę i przypływ nowej energii. Wpadałem także na pomysł zaczynania anegdot od jakiegoś mądrego zdania czy powiedzenia, aby nadać im trochę mocy i godności.

Na pytanie Twoje odpowiem trochę z opóźnieniem, bo przecież „śpiesz się powoli”, nie będę się też zbytnio rozwodził, bo to „czyny mówią same za siebie”, a skoro „praktyka czyni mistrza” i „potrzeba matką wynalazku” to oto skrypt, który do pustych plików wpisuje komunikat File did not save correctly:

Const ForWriting = 2



Set objFSO = CreateObject("Scripting.FileSystemObject")

Set objFolder = objFSO.GetFolder("C:\Logs")



Set colItems = objFolder.Files



For Each objItem in colItems

    If objItem.Size = 0 Then

        Set objFile = objFSO.OpenTextFile(objItem.Path, ForWriting)

        objFile.WriteLine "File did not save correctly."

        objFile.Close

    End If

Next

Zaczynamy od zdefiniowania stałej ForWriting i ustawienia jej wartości na 2; będzie nam ona potrzebna w celu wpisaniu komunikatu File did not save correctly do każdego pustego pliku. Po zdefiniowaniu tej stałej tworzymy wystąpienie obiektu Scripting.FileSystemObject, a następnie za pomocą metody GetFolder łączymy się z folderem C:\Logs:

Set objFolder = objFSO.GetFolder("C:\Logs")

Po połączeniu się z folderem pobieramy kolekcję wszystkich plików zawartych w C:\Logs. Robimy to za pomocą odwołania do (colItems) właściwości Files naszego folderu:

Set colItems = objFolder.Files

Mamy teraz do dyspozycji kolekcję wszystkich plików z C:\Logs. Tylko co począć z taką kolekcją?

Mamy kilka pomysłów. Możemy na przykład ustawić pętlę For Each, która przejdzie przez każdy plik kolekcji. Wewnątrz pętli sprawdzamy czy rozmiar pliku (Size) to 0 bajtów:

If objItem.Size = 0 Then

Jeżeli powyższy wiersz kodu zwróci nam wartość True, to oznacza to, że mamy do czynienia z pustym plikiem. Mając to na uwadze, powracamy do obiektu FileSystemObject, tym razem w celu otworzenia pliku do zapisu:

Set objFile = objFSO.OpenTextFile(objItem.Path, ForWriting)
Uwaga: Skąd obiekt FileSystemObject wie, który plik chcemy otworzyć? Bo to całkiem niegłupi obiekt i wie wszystko. Mając jednak na uwadze dewizę „przezorny zawsze ubezpieczony”, nadajemy mu dodatkowo właściwość Path pliku, czyli jego ścieżkę. Powinna ona wyglądać jakoś tak: C:\Logs\Test.txt. Czy po uzyskaniu takiej informacji nasz obiekt FileSystemObject mógłby nie wiedzieć który plik otworzyć? Wątpię.

Po otworzeniu pliku korzystamy z metody WriteLine i zastępujemy pusty plik komunikatem File did not save correctly:

objFile.WriteLine "File did not save correctly."

Po zrobieniu tego zamykamy plik, po czym powracamy do początku pętli i powtarzamy cały proces dla następnego elementu kolekcji:

Mało skomplikowane, prawda?

Zawsze jest oczywiście jakieś „ale”. Powyższy skrypt ma jedną zasadniczą wadę – działa tylko na komputerze lokalnym. Co więc, jeżeli musimy go uruchomić na komputerze zdalnym?

Stanowi to w sumie dość duży problem, ponieważ obiekt FileSystemObject nie jest przystosowany do komputerów zdalnych. Oczywiście, jak zawsze, można ten problem obejść – można skorzystać z WMI w celu pobrania kolekcji wszystkich plików w folderze zdalnym, a następnie, korzystając ze ścieżek UNC oraz udziałów administracyjnych, przymusić go do zapisania komunikatów w folderze. Powinno zadziałać, oczywiście przy założeniu, że korzystacie z udziałów administracyjnych:

Const ForWriting = 2



Set objFSO = CreateObject("Scripting.FileSystemObject")



strComputer = "gizmonic"



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



Set colItems = objWMIService.ExecQuery _

    ("ASSOCIATORS OF {Win32_Directory.Name='C:\Temp'} Where " _

        & "ResultClass = CIM_DataFile")



For Each objItem In colItems

    If objItem.FileSize = 0 Then       

        strFilePath = "\\" & strComputer & "\C$\Temp\" & _

            objItem.FileName & "." & objItem.Extension

        Set objFile = objFSO.OpenTextFile(strFilePath, ForWriting)

        objFile.WriteLine "File did not save correctly."

        objFile.Close

    End If

Next

Tego skryptu nie będziemy dziś szczegółowo omawiać. Jeżeli potrzebujecie informacji na temat pracy z plikami tekstowymi na komputerze zdalnym, rzućcie okiem na nasz artykuł na ten temat na pracy z plikami tekstowymi na komputerach zdalnych. Tam również znajdziecie odpowiedź na pytanie, czym są udziały administracyjne.

Powinno starczyć, CE. Pamiętaj tylko, jeżeli brałeś udział w naszej Skrypciarskiej Olimpiadzie i masz zastrzeżenia co do wyniku, lub chciałbyś przysłać poprawioną wersję skryptu, to wiedz, że chociaż termin już upłynął, to nagrody losować będziemy dopiero 10 marca, więc teoretycznie masz jeszcze szansę… Tak czy siak, 10 marca wyłonimy zwycięzców i ustalimy, kto zasługuje na nasz certyfikat.

Upraszamy ponadto o nie skarżenie się na 5. dyscyplinę w sekcji dla początkujących.

Lepiej późno, niż wcale.

Wszystko dobre, co się dobrze kończy.

 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne