Centrum skryptów - Systemy operacyjne

Czy można zmienić oznaczenie czasu ostatniej modyfikacji wszystkich plików w folderze?

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.

Czy można zmienić oznaczenie czasu ostatniej modyfikacji wszystkich plików w folderze?

Cześć Skrypciarze! Pytanie

Cześć, Skrypciarze! Czy można zmienić oznaczenie czasu ostatniej modyfikacji wszystkich plików w folderze? Najlepiej, aby oznaczenie czasu modyfikacji w każdym kolejnym pliku było o minutę późniejsze.

-- AF

Cześć Skrypciarze! Odpowiedź

Cześć, AF. Fajnie, że robisz sobie przerwę w rozwiązywaniu zadań Olimpiady Skrypciarskiej (j.ang.). Czy chcemy w ten sposób wyrazić troskę o to, że może się przepracowujesz? Bynajmniej. Chodzi o nasze przepracowanie. W czasie pisania dzisiejszego artykułu Olimpiada trwała zaledwie od paru godzin, a dostaliśmy kilkaset rozwiązań. Każde z nich musimy przetestować, ocenić i odnotować gdzie trzeba. Nie minęło jeszcze nawet pół dnia, a my już zalegamy z oceną wyników!

Ale nie martwcie się o nas. Zaleganie z różnymi rzeczami to dla nas chleb powszedni.

Tak czy inaczej, uważamy, że należy się nam przerwa. Dlatego też zajmiemy się teraz zmienianiem daty modyfikacji plików.

Odpowiedź jest prosta: to niemożliwe. A przynajmniej nie mamy pojęcia, jak to zrobić za pomocą VBScript; z tego co wiemy, ani FileSystemObject, ani Shell Application, ani WMI nie ma opcji pozwalającej na modyfikowanie oznaczeń czasu w systemie plików. Jeśli jednak niestraszny Ci Windows PowerShell (j.ang.), możesz wykonać swoje zadanie z minimalnym wysiłkiem:

$a = Get-Date "2/13/2007 8:00 AM"



$b = Get-ChildItem "C:\Scripts"



foreach ($i in $b)

{

    $i.LastWriteTime = $a

    $a = $a.AddMinutes(1)    

}



$b

Jak widać, obywamy się bez fajerwerków – od zastosowania komandletu (czyli polecenia PowerShell) Get-Date do utworzenia obiektu $a o wartości czasowej: 8:00, 13 lutego 2007 r. (data podana w formacie MM/DD/RRRR):

$a = Get-Date "2/13/2007 8:00 AM"

Jak się domyślasz, wartość $a oznacza początkową datę i godzinę.

Następnie za pomocą poniższego wiersza kodu i komandletu Get-ChildItem pobieramy kolekcję wszystkich plików znajdujących się w folderze C:\Scripts:

$b = Get-ChildItem "C:\Scripts"

A swoją drogą, AF, być może zależy Ci na alfebetycznym przesortowaniu plików. Okazuje się, że jest to tak łatwe, że nawet Olimpiada Skrypciarska nie stanęła nam na drodze; komandlet Get-ChildItem domyślnie zwraca kolekcję już posortowaną. Oznacza to, że otrzymujemy dane w takiej postaci:

Mode                LastWriteTime     Length Name

----                -------------     ------ ----

-a---         2/11/2007   3:31 PM         89 1024.ps1

-a---        12/13/2006   9:11 AM         56 1026.ps1

-a---         1/21/2007   6:19 PM        133 1030.ps1

-a---          8/4/2006   4:41 PM         99 1032.ps1

-a---          2/9/2006   6:04 PM        146 1035.ps1

-a---         1/22/2005   8:05 AM         68 1045.ps1

Nie było trudno, no nie? I wiesz co? Zmodyfikowanie właściwości LastWriteTime każdego z naszych plików nie jest dużo trudniejsze. Do tego właśnie posłuży nam poniższy fragment kodu:

foreach ($i in $b)

    {

        $i.LastWriteTime = $a

        $a = $a.AddMinutes(1)    

    }

Włączamy tu pętlę For Each, która przechodzi przez wszystkie elementy obiektu $b; obiekt ten obejmuje pliki zawarte w folderze C:\Scripts:

foreach ($i in $b)

Każde uruchomienie pętli wiąże sie z wykonaniem dwóch czynności. Po pierwsze, zmieniamy wartość właściwości LastWriteTime pliku (plik oznaczony jest zmienną $i) tak, by odpowiadała ona wartości zapisanej w obiekcie $a:

$i.LastWriteTime = $a

Oznacza to, że właściwość LastWriteTime pierwszego pliku będzie odpowiadać godzinie 8:00, 13 lutego 2007 r.

To by wystarczyło, gdybyśmy chcieli ustawić jednakowy czas modyfikacji wszystkich plików w folderze C:\Scripts. Jednak nie o to chodzi – poszczególne wartości mają się od siebie nieco różnić. Dlatego nasza pętla zawiera jeszcze jeden wiersz kodu:

$a = $a.AddMinutes(1)

Używamy tu metody AddMinutes, która zwiększa wartość czasową (obiekt $a) o 1 minutę (stąd jedynka użyta jako parametr metody AddMinutes). Jak zapewne pamiętacie, początkowa wartosć $a odpowiadała 8:00, 13 lutego 2007 r. Dodajemy minutę, uzyskując 8:01, 13 lutego 2007 r. Trzeci plik z kolei bedzie miał czas modyfikacji późniejszy o jeszcze jedną minutę itd.

Ostateczny wynik będzie wyglądał tak:

Mode                LastWriteTime     Length Name

----                -------------     ------ ----

-a---         2/13/2007   8:00 AM         89 1024.ps1

-a---         2/13/2007   8:01 AM         56 1026.ps1

-a---         2/13/2007   8:02 AM        133 1030.ps1

-a---         2/13/2007   8:03 AM         99 1032.ps1

-a---         2/13/2007   8:04 AM        146 1035.ps1

-a---         2/13/2007   8:05 AM         68 1045.ps1

Czyli tak właśnie, jak chcieliśmy.

No cóż, pora znów zająć się Olimpiadą. No chyba, AF, że masz jeszcze jakieś pytania? Nie? Trudno. To może ktoś inny ma jakieś pytania? Proszę pani, ma pani jakieś pytania? Może pan? Ktokolwiek…

 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne