Pola czasu w linkach symbolicznych
Po wprowadzeniu zmian w następujących polach związanych z czasem w linku symbolicznym ("symlink"), aktualizacje mają teraz wpływ na sam symlink, a nie element docelowy:
Poprzednie zachowanie
Wcześniej zaktualizowanie dowolnego pola powiązanego z czasem na symlinku wpłynęło na pola obiektu docelowego symlinku.
Rozważmy następujący program, który drukuje różne wartości pól czasu w pliku i jego link symboliczny, aktualizuje wartości pól czasu łącza symlinku do 1 dnia później, a następnie ponownie wyświetla wartości pól czasu zarówno w pliku, jak i symlinku.
string filename = "file";
string linkname = "link";
// Create a file and symlink.
File.Create(filename).Dispose();
File.CreateSymbolicLink(linkname, filename);
Console.WriteLine("Before update:");
PrintMetadata(filename);
PrintMetadata(linkname);
UpdateMetadata(linkname);
Console.WriteLine("\nAfter update:");
PrintMetadata(filename);
PrintMetadata(linkname);
static void UpdateMetadata(string filename)
{
DateTime tomorrow = DateTime.Now.AddDays(1);
File.SetCreationTime(filename, tomorrow);
File.SetLastAccessTime(filename, tomorrow);
File.SetLastWriteTime(filename, tomorrow);
File.SetAttributes(filename, File.GetAttributes(filename) | FileAttributes.Offline);
}
static void PrintMetadata(string filename)
{
Console.WriteLine($"---{filename}---");
Console.WriteLine("Creation:\t" + File.GetCreationTime(filename));
Console.WriteLine("Last access:\t" + File.GetLastAccessTime(filename));
Console.WriteLine("Last write:\t" + File.GetLastWriteTime(filename));
Console.WriteLine("Attributes:\t" + File.GetAttributes(filename));
}
Wcześniej po zaktualizowaniu wartości w symlinku zaktualizowano tylko pola czasu pliku docelowego. Dane wyjściowe poprzedniego programu były następujące:
Before update:
---file---
Creation: 9/29/2022 10:35:40 AM
Last access: 9/29/2022 10:35:40 AM
Last write: 9/29/2022 10:35:40 AM
Attributes: Archive
---link---
Creation: 9/29/2022 10:35:40 AM
Last access: 9/29/2022 10:35:40 AM
Last write: 9/29/2022 10:35:40 AM
Attributes: Archive, ReparsePoint
After update:
---file---
Creation: 9/30/2022 10:35:40 AM
Last access: 9/30/2022 10:35:40 AM
Last write: 9/30/2022 10:35:40 AM
Attributes: Archive
---link---
Creation: 9/29/2022 10:35:40 AM
Last access: 9/29/2022 10:35:40 AM
Last write: 9/29/2022 10:35:40 AM
Attributes: Archive, ReparsePoint, Offline
Nowe zachowanie
Począwszy od platformy .NET 7, aktualizowanie dowolnego pola powiązanego z czasem na symlinku wpływa na pola samego łącza symlinku, a nie pliku docelowego.
Dane wyjściowe programu pokazane w sekcji Poprzednie zachowanie są następujące:
Before update:
---file---
Creation: 9/29/2022 10:33:39 AM
Last access: 9/29/2022 10:33:39 AM
Last write: 9/29/2022 10:33:39 AM
Attributes: Archive
---link---
Creation: 9/29/2022 10:33:39 AM
Last access: 9/29/2022 10:33:39 AM
Last write: 9/29/2022 10:33:39 AM
Attributes: Archive, ReparsePoint
After update:
---file---
Creation: 9/29/2022 10:33:39 AM
Last access: 9/29/2022 10:33:39 AM
Last write: 9/29/2022 10:33:39 AM
Attributes: Archive
---link---
Creation: 9/30/2022 10:33:39 AM
Last access: 9/30/2022 10:33:39 AM
Last write: 9/30/2022 10:33:39 AM
Attributes: Archive, ReparsePoint, Offline
Wprowadzona wersja
.NET 7 (wersja zapoznawcza 1)
Typ zmiany powodującej niezgodność
Ta zmiana może mieć wpływ na zgodność binarną.
Przyczyna wprowadzenia zmiany
Poprzednie zachowanie było nieoczekiwane i niepożądane w niektórych przypadkach:
- Była niespójna z zachowaniem właściwości i metod, które pobierają te same pola.
- Nie można było również zaktualizować pól w samym symlinku przy użyciu interfejsów API platformy .NET.
Zalecana akcja
Jeśli polegasz na tym zachowaniu, aby ustawić wartości na obiekcie docelowym syymlinku, ustawienie jednego z *Time
pól w symlinku nie wpłynie już na cel. Możesz użyć nowych interfejsów API linku symbolicznego, aby uzyskać obiekt docelowy symlinku, a następnie zaktualizować ten obiekt systemu plików.
FileSystemInfo? targetInfo = linkInfo.ResolveLinkTarget(returnFinalTarget: true);
if (targetInfo != null)
{
// Update the properties accordingly.
targetInfo.LastWriteTime = DateTime.Now;
}
Dotyczy interfejsów API
- System.IO.Directory.SetCreationTime(String, DateTime)
- System.IO.Directory.SetCreationTimeUtc(String, DateTime)
- System.IO.Directory.SetLastAccessTime(String, DateTime)
- System.IO.Directory.SetLastAccessTimeUtc(String, DateTime)
- System.IO.Directory.SetLastWriteTime(String, DateTime)
- System.IO.Directory.SetLastWriteTimeUtc(String, DateTime)
- System.IO.File.SetCreationTime(String, DateTime)
- System.IO.File.SetCreationTimeUtc(String, DateTime)
- System.IO.File.SetLastAccessTime(String, DateTime)
- System.IO.File.SetLastAccessTimeUtc(String, DateTime)
- System.IO.File.SetLastWriteTime(String, DateTime)
- System.IO.File.SetLastWriteTimeUtc(String, DateTime)
- System.IO.FileSystemInfo.CreationTime
- System.IO.FileSystemInfo.CreationTimeUtc
- System.IO.FileSystemInfo.LastAccessTime
- System.IO.FileSystemInfo.LastAccessTimeUtc
- System.IO.FileSystemInfo.LastWriteTime
- System.IO.FileSystemInfo.LastWriteTimeUtc