soporta sistema simbólicos simbólico simbolico quitar puede link enlaces enlace eliminar directorio crear carpetas archivos archivo c# symlink

c# - sistema - Compruebe si un archivo es real o un enlace simbólico.



quitar enlace simbolico windows 10 (6)

¿Hay alguna forma de saber si se usa C # si un archivo es real o un enlace simbólico?

He buscado en los documentos de MSDN W32 ( http://msdn.microsoft.com/en-us/library/aa364232(VS.85).aspx ), y no puedo encontrar nada para verificar esto. Estoy usando CreateSymbolicLink desde aquí, y está funcionando bien.


De acuerdo con esta respuesta a la pregunta de desbordamiento de pila, averigüe si un archivo es un enlace simbólico en PowerShell , obtener los System.IO.FileAttributes para el archivo (a través de File.GetAttributes ) y probar el bit ReparsePoint. Si se establece el bit, es un enlace simbólico o un punto de unión. Si no, es un archivo regular (o enlace duro).


Este es un ejemplo de la diferenciación de archivos y directorios de enlaces a archivos y enlaces a directorios.

Los enlaces a archivos o directorios mantienen sus propios atributos (fecha de creación, permisos) separados de sus destinos.

Los enlaces de archivos se pueden eliminar (por ejemplo, usando "del") sin afectar el archivo de destino.

Los enlaces de directorio pueden eliminarse (por ejemplo, "rmdir") sin afectar el directorio de destino. Tenga cuidado al usar "rd / s". Esto eliminará el destino del enlace del directorio.

El FileAttributes clave de FileAttributes para verificar tanto FileInfo como DirectoryInfo es FileAttributes.ReparsePoint .

static void Main( string[] args ) { FileInfo file_info = new FileInfo(args[0]); DirectoryInfo directory_info = new DirectoryInfo(args[0]); bool is_file = file_info.Exists; bool is_directory = directory_info.Exists; if (is_file) { Console.WriteLine(file_info.ToString() + " is a file"); if ( file_info.Attributes.HasFlag(FileAttributes.ReparsePoint) ) Console.WriteLine(args[0] + " is a Windows file link"); } else if (is_directory) { Console.WriteLine(directory_info.ToString() + " is a directory"); if ( directory_info.Attributes.HasFlag(FileAttributes.ReparsePoint) ) Console.WriteLine(args[0] + " is a Windows directory link"); }


Prueba que las respuestas anteriores no son confiables. Finalmente obtuve la solución correcta de MSDN :

Para determinar si un directorio especificado es una carpeta montada, primero llame a la función GetFileAttributes e inspeccione el indicador FILE_ATTRIBUTE_REPARSE_POINT en el valor de retorno para ver si el directorio tiene un punto de análisis asociado. Si lo hace, use las funciones FindFirstFile y FindNextFile para obtener la etiqueta de repetición en el miembro dwReserved0 de la estructura WIN32_FIND_DATA. Para determinar si el punto de análisis es una carpeta montada (y no otra forma de punto de análisis), compruebe si el valor de la etiqueta es igual al valor IO_REPARSE_TAG_MOUNT_POINT. Para más información, vea Puntos de Reparse.


Tengo un código fuente para enlaces simbólicos publicado en mi blog que te permitirá:

  • crear enlaces simbólicos
  • comprobar si una ruta es un enlace simbólico
  • recuperar el objetivo de un enlace simbólico

También contiene casos de prueba NUnit, que es posible que desee ampliar.

El bit carnoso es:

private static SafeFileHandle getFileHandle(string path) { return CreateFile(path, genericReadAccess, shareModeAll, IntPtr.Zero, openExisting, fileFlagsForOpenReparsePointAndBackupSemantics, IntPtr.Zero); } public static string GetTarget(string path) { SymbolicLinkReparseData reparseDataBuffer; using (SafeFileHandle fileHandle = getFileHandle(path)) { if (fileHandle.IsInvalid) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } int outBufferSize = Marshal.SizeOf(typeof(SymbolicLinkReparseData)); IntPtr outBuffer = IntPtr.Zero; try { outBuffer = Marshal.AllocHGlobal(outBufferSize); int bytesReturned; bool success = DeviceIoControl( fileHandle.DangerousGetHandle(), ioctlCommandGetReparsePoint, IntPtr.Zero, 0, outBuffer, outBufferSize, out bytesReturned, IntPtr.Zero); fileHandle.Close(); if (!success) { if (((uint)Marshal.GetHRForLastWin32Error()) == pathNotAReparsePointError) { return null; } Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } reparseDataBuffer = (SymbolicLinkReparseData)Marshal.PtrToStructure( outBuffer, typeof(SymbolicLinkReparseData)); } finally { Marshal.FreeHGlobal(outBuffer); } } if (reparseDataBuffer.ReparseTag != symLinkTag) { return null; } string target = Encoding.Unicode.GetString(reparseDataBuffer.PathBuffer, reparseDataBuffer.PrintNameOffset, reparseDataBuffer.PrintNameLength); return target; }

Es decir:


GetFileInformationByHandle rellena una estructura BY_HANDLE_FILE_INFORMATION que tiene un campo dwFileAttributes donde los bits se configuran con información sobre los atributos del archivo (detalles here ). En particular, mira el bit en la máscara ...:

FILE_ATTRIBUTE_REPARSE_POINT 1024 0x0400

Un archivo o directorio que tiene un punto de análisis asociado o un archivo que es un enlace simbólico.


private bool IsSymbolic(string path) { FileInfo pathInfo = new FileInfo(path); return pathInfo.Attributes.HasFlag(FileAttributes.ReparsePoint); }