Udostępnij za pośrednictwem


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.

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