Campos de tiempo en vínculos simbólicos

Cuando se realizan cambios en los siguientes campos relacionados con el tiempo en un vínculo simbólico ("symlink"), las actualizaciones ahora afectan al propio vínculo simbólico y no al destino:

Comportamiento anterior

Anteriormente, la actualización de cualquiera de los campos relacionados con el tiempo en un vínculo simbólico afectaba a los campos de destino del vínculo simbólico.

Tenga en cuenta el programa siguiente, que imprime los distintos valores de campo de tiempo en un archivo y su vínculo simbólico, actualiza los valores del campo de tiempo del vínculo simbólico a un día más tarde y, a continuación, vuelve a imprimir los valores del campo de tiempo en el archivo y el vínculo simbólico.

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));
}

Antes, después de actualizar los valores en el vínculo simbólico, solo se actualizaban los campos de tiempo del archivo de destino. La salida del programa anterior era la siguiente:

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

Comportamiento nuevo

A partir de .NET 7, la actualización de cualquiera de los campos relacionados con el tiempo en un vínculo simbólico afecta a los campos del propio vínculo simbólico y no al archivo de destino.

La salida del programa que se muestra en la sección Comportamiento anterior es la siguiente:

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

Versión introducida

.NET 7 (versión preliminar 1)

Tipo de cambio importante

Este cambio puede afectar a la compatibilidad binaria.

Motivo del cambio

El comportamiento anterior era inesperado y, en algunos casos, no deseado:

  • Era incoherente con el comportamiento de las propiedades y los métodos que obtienen los mismos campos.
  • También era imposible actualizar realmente los campos del propio vínculo simbólico mediante las API de .NET.

Si se basaba en este comportamiento para establecer valores en el destino del vínculo simbólico, establecer uno de los campos *Time de un vínculo simbólico ya no afectará al destino. Puede usar las nuevas API de vínculo simbólico para obtener el destino de un vínculo simbólico y actualizar ese objeto de sistema de archivos en su lugar.

FileSystemInfo? targetInfo = linkInfo.ResolveLinkTarget(returnFinalTarget: true);
if (targetInfo  != null)
{
    // Update the properties accordingly.
    targetInfo.LastWriteTime = DateTime.Now;
}

API afectadas