too longpathsenabled long length how disable c# .net filenames case-sensitive filepath

c# - longpathsenabled - windows disable path length limit



C#Filepath Recasing (6)

Estoy intentando escribir una función de miembro estático en C # o encontrar uno en .NET Framework que volverá a presentar una ruta de archivo a lo que especifica el sistema de archivos.

Ejemplo:

string filepath = @"C:/temp.txt"; filepath = FileUtility.RecaseFilepath(filepath); // filepath = C:/Temp.TXT // Where the real fully qualified filepath in the NTFS volume is C:/Temp.TXT

He intentado el siguiente código a continuación y muchas variantes y todavía no funciona. Sé que Windows no distingue entre mayúsculas y minúsculas en general, pero necesito pasar estas rutas de acceso de archivos a ClearCase, que considera el alojamiento de la ruta del archivo, ya que es una aplicación de Unix y Windows.

public static string GetProperFilePathCapitalization(string filepath) { string result = ""; try { result = Path.GetFullPath(filepath); DirectoryInfo dir = new DirectoryInfo(Path.GetDirectoryName(result)); FileInfo[] fi = dir.GetFiles(Path.GetFileName(result)); if (fi.Length > 0) { result = fi[0].FullName; } } catch (Exception) { result = filepath; } return result; }


Esta es una implementación bastante simple que supone que todos los archivos y directorios están disponibles y son accesibles:

static string GetProperDirectoryCapitalization(DirectoryInfo dirInfo) { DirectoryInfo parentDirInfo = dirInfo.Parent; if (null == parentDirInfo) return dirInfo.Name; return Path.Combine(GetProperDirectoryCapitalization(parentDirInfo), parentDirInfo.GetDirectories(dirInfo.Name)[0].Name); } static string GetProperFilePathCapitalization(string filename) { FileInfo fileInfo = new FileInfo(filename); DirectoryInfo dirInfo = fileInfo.Directory; return Path.Combine(GetProperDirectoryCapitalization(dirInfo), dirInfo.GetFiles(fileInfo.Name)[0].Name); }

Sin embargo, hay un error con esto: las rutas relativas se convierten en rutas absolutas. Tu código original anterior hizo lo mismo, así que supongo que quieres este comportamiento.


Puede buscar el archivo en el que desea obtener el caso y devolver los resultados de su búsqueda (desea verificar la carcasa de un archivo que existe, ¿no?). Algo como esto:

public static string GetProperFilePathCapitalization(string filepath) { string directoryPath = Path.GetDirectoryName(filepath); string[] files = Directory.GetFiles(directoryPath, Path.GetFileName(filepath)); return files[0]; }

Es esto lo que estás buscando?


Lo que sigue funciona bien en la medida en que lo probé ... la única pega es que la API utilizada está disponible solo en Vista.

static void Main(string[] args) { using (FileStream fs = File.OpenRead(@"D:/temp/case/mytest.txt")) { StringBuilder path = new StringBuilder(512); GetFinalPathNameByHandle(fs.SafeFileHandle.DangerousGetHandle(), path, path.Capacity, 0); Console.WriteLine(path.ToString()); } } [DllImport("kernel32.dll", SetLastError = true)] static extern int GetFinalPathNameByHandle(IntPtr handle, [In, Out] StringBuilder path, int bufLen, int flags);


Tengo algo más eficiente pero:

1) No parece funcionar para todos los casos. (No he descubierto el patrón de qué archivos y directorios recibe correctamente la caja y cuáles no).

2) Es específico de Windows.

static string GetProperFilePathCapitalization1(string filename) { StringBuilder sb = new StringBuilder(260); int length = GetLongPathName(filename, sb, sb.Capacity); if (length > sb.Capacity) { sb.Capacity = length; length = GetLongPathName(filename, sb, sb.Capacity); } if (0 == length) throw new Win32Exception("GetLongPathName"); return sb.ToString(); } [DllImport("kernel32.dll")] static extern int GetLongPathName(string path, StringBuilder pszPath, int cchPath);


La respuesta de @Antes anterior debe obtener crédito como la respuesta aceptada. Sin embargo, lo modifiqué un poco para mis propósitos. El enfoque está empaquetado como métodos de extensión para FileInfo y DirectoryInfo, y también devuelve los corregidos.

public static DirectoryInfo GetProperCasedDirectoryInfo(this DirectoryInfo dirInfo) { // Inspired by http://.com/a/479198/244342 if (!dirInfo.Exists) { // Will not be able to match filesystem return dirInfo; } DirectoryInfo parentDirInfo = dirInfo.Parent; if (parentDirInfo == null) { return dirInfo; } else { return parentDirInfo.GetProperCasedDirectoryInfo().GetDirectories(dirInfo.Name)[0]; } } public static FileInfo GetProperCasedFileInfo(this FileInfo fileInfo) { // Inspired by http://.com/a/479198/244342 if (!fileInfo.Exists) { // Will not be able to match filesystem return fileInfo; } return fileInfo.Directory.GetProperCasedDirectoryInfo().GetFiles(fileInfo.Name)[0]; }

Me he estado golpeando la cabeza sobre algunos problemas de inconsistencia de casos con FileInfo. Para garantizar la solidez, paso a mayúsculas cuando comparo o almaceno las rutas. Para aclarar el propósito del código, también tengo estos métodos de extensión:

public static string GetPathForKey(this FileInfo File) { return File.FullName.ToUpperInvariant(); } public static string GetDirectoryForKey(this FileInfo File) { return File.DirectoryName.ToUpperInvariant(); }


Querrá que el sistema encuentre el archivo por usted. Hago esto fingiendo que no sé la ruta exacta, es decir, tengo la búsqueda del sistema:

var fileName = Path.GetFileName(filePath); var dir = Path.GetDirectoryName(filePath); var filePaths = Directory.GetFiles(dir, fileName, SearchOption.TopDirectoryOnly); var caseCorrectedFilePath = filePaths.FirstOrDefault();

Entonces buscamos en el directorio, filtrando el nombre exacto del archivo y limitando la búsqueda al directorio actual solamente (sin recursividad).

Esto devuelve una matriz de cadenas que contiene la ruta del archivo único con la carcasa correcta (si el archivo existe) o nada (si el archivo no existe).

Una advertencia: es posible que deba deshabilitar los comodines en la ruta de entrada, porque este enfoque los acepta y puede encontrar varios archivos como resultado.

Editar

La letra de la unidad parece seguir la carcasa que proporcionamos. Además, esto debe probarse para rutas UNC.