.net - rutas - ¿Cuál es la forma correcta de verificar si una ruta es una ruta UNC o una ruta local?
rutas absolutas y relativas linux (6)
La forma más fácil de comprobar si una ruta es una ruta UNC es, por supuesto, verificar si el primer carácter en la ruta completa es una letra o barra invertida. ¿Es esta una buena solución o podría haber problemas con ella?
Mi problema específico es que quiero crear un objeto System.IO.DriveInfo si hay una letra de unidad en la ruta.
Como una ruta sin dos barras invertidas en la primera y la segunda posición es, por definición, una ruta no UNC, esta es una forma segura de hacer esta determinación.
Una ruta con una letra de unidad en la primera posición (c :) es una ruta local rooteada.
Un camino sin cualquiera de estas cosas (myfolder / blah) es una ruta local relativa. Esto incluye una ruta con solo una barra (/ myfolder / blah).
Prueba este método de extensión
public static bool IsUncDrive(this DriveInfo info) {
Uri uri = null;
if ( !Uri.TryCreate(info.Name, UriKind.Absolute, out uri) ) {
return false;
}
return uri.IsUnc;
}
Esta es mi versión:
public static bool IsUnc(string path)
{
string root = Path.GetPathRoot(path);
// Check if root starts with "//", clearly an UNC
if (root.StartsWith(@"//"))
return true;
// Check if the drive is a network drive
DriveInfo drive = new DriveInfo(root);
if (drive.DriveType == DriveType.Network)
return true;
return false;
}
La ventaja de esta versión sobre la versión de @JaredPars es que esto admite cualquier ruta, no solo DriveInfo
.
Un truco que he encontrado es usar dInfo.FullName.StartsWith(String.Empty.PadLeft(2, IO.Path.DirectorySeparatorChar))
donde dInfo es un objeto DirectoryInfo - si esa verificación devuelve True, entonces es una ruta UNC, de lo contrario es una ruta local
Tal vez esta respuesta puede ser útil para alguien que solo quiere validar servidores UNC + subdirectorios compartidos , por ejemplo ruta al depósito de red como
-
//Server1/Share1
-
//Server2/Share22/Dir1/Dir2
-
//Server3
Use la siguiente expresión regular:
^////([A-Za-z0-9_/-]{1,32}[///]){0,10}[A-Za-z0-9_/-]{1,32}$
- reemplace
32
(2 veces) con la longitud máxima permitida del nombre del servidor / directorio - reemplace
10
con la profundidad de ruta máxima permitida (recuento máximo de directorios) - extienda
[A-Za-z0-9_/-]
(2 veces) si le falta algún carácter permitido en el nombre del servidor / directorio
Lo he probado con éxito. ¡Disfrutar!
El enfoque más preciso será usar algún código de interoperabilidad de shlwapi.dll
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
[ResourceExposure(ResourceScope.None)]
[return: MarshalAsAttribute(UnmanagedType.Bool)]
internal static extern bool PathIsUNC([MarshalAsAttribute(UnmanagedType.LPWStr), In] string pszPath);
Entonces lo llamarías así:
/// <summary>
/// Determines if the string is a valid Universal Naming Convention (UNC)
/// for a server and share path.
/// </summary>
/// <param name="path">The path to be tested.</param>
/// <returns><see langword="true"/> if the path is a valid UNC path;
/// otherwise, <see langword="false"/>.</returns>
public static bool IsUncPath(string path)
{
return PathIsUNC(path);
}
@JaredPar tiene la mejor respuesta usando código puramente administrado .