Check whether a path is valid

I am just wondering: I am looking for a way to validate if a given path is valid. (Note: I do not want to check if a file is existing! I only want to proof the validity of the path - So if a file could possibly exists at the location).

Problem is, I can't find anything in the .Net API. Due to the many formats and locations that Windows supports, I'd rather use something MS-native.

Since the function should be able to check against:

  • Relative Paths (./)
  • Absolute Paths (c:\tmp)
  • UNC-Pathes (\some-pc\c$)
  • NTFS-Limitations like the full path 1024 chars - If I am not mistaken exceeding the path will make a file inaccessible for many internal Windows functions. Renaming it with Explorer still works
  • Volume GUID Paths : "\?\Volume{GUID}\somefile.foo

Does anyone have a function like this?

166693 次浏览

Try Uri.IsWellFormedUriString():

  • The string is not correctly escaped.

      http://www.example.com/path???/file name
    
  • The string is an absolute Uri that represents an implicit file Uri.

      c:\\directory\filename
    
  • The string is an absolute URI that is missing a slash before the path.

      file://c:/directory/filename
    
  • The string contains unescaped backslashes even if they are treated as forward slashes.

      http:\\host/path/file
    
  • The string represents a hierarchical absolute Uri and does not contain "://".

      www.example.com/path/file
    
  • The parser for the Uri.Scheme indicates that the original string was not well-formed.

      The example depends on the scheme of the URI.
    

The closest I have come is by trying to create it, and seeing if it succeeds.

Get the invalid chars from System.IO.Path.GetInvalidPathChars(); and check if your string (Directory path) contains those or not.

You could try using Path.IsPathRooted() in combination with Path.GetInvalidFileNameChars() to make sure the path is half-way okay.

private bool IsValidPath(string path)
{
Regex driveCheck = new Regex(@"^[a-zA-Z]:\\$");
if (!driveCheck.IsMatch(path.Substring(0, 3))) return false;
string strTheseAreInvalidFileNameChars = new string(Path.GetInvalidPathChars());
strTheseAreInvalidFileNameChars += @":/?*" + "\"";
Regex containsABadCharacter = new Regex("[" + Regex.Escape(strTheseAreInvalidFileNameChars) + "]");
if (containsABadCharacter.IsMatch(path.Substring(3, path.Length - 3)))
return false;


DirectoryInfo dir = new DirectoryInfo(Path.GetFullPath(path));
if (!dir.Exists)
dir.Create();
return true;
}

You can try this code:

try
{
Path.GetDirectoryName(myPath);
}
catch
{
// Path is not valid
}

I'm not sure it covers all the cases...

private bool IsValidPath(string path)
{
Regex driveCheck = new Regex(@"^[a-zA-Z]:\\$");


if (string.IsNullOrWhiteSpace(path) || path.Length < 3)
{
return false;
}


if (!driveCheck.IsMatch(path.Substring(0, 3)))
{
return false;
}


var x1 = (path.Substring(3, path.Length - 3));
string strTheseAreInvalidFileNameChars = new string(Path.GetInvalidPathChars());
strTheseAreInvalidFileNameChars += @":?*";
Regex containsABadCharacter = new Regex("[" + Regex.Escape(strTheseAreInvalidFileNameChars) + "]");


if (containsABadCharacter.IsMatch(path.Substring(3, path.Length - 3)))
{
return false;
}


var driveLetterWithColonAndSlash = Path.GetPathRoot(path);


if (!DriveInfo.GetDrives().Any(x => x.Name == driveLetterWithColonAndSlash))
{
return false;
}


return true;
}

I haven't had any problems with the code below. (Relative paths must start with '/' or '\').

private bool IsValidPath(string path, bool allowRelativePaths = false)
{
bool isValid = true;


try
{
string fullPath = Path.GetFullPath(path);


if (allowRelativePaths)
{
isValid = Path.IsPathRooted(path);
}
else
{
string root = Path.GetPathRoot(path);
isValid = string.IsNullOrEmpty(root.Trim(new char[] { '\\', '/' })) == false;
}
}
catch(Exception ex)
{
isValid = false;
}


return isValid;
}

For example these would return false:

IsValidPath("C:/abc*d");
IsValidPath("C:/abc?d");
IsValidPath("C:/abc\"d");
IsValidPath("C:/abc<d");
IsValidPath("C:/abc>d");
IsValidPath("C:/abc|d");
IsValidPath("C:/abc:d");
IsValidPath("");
IsValidPath("./abc");
IsValidPath("./abc", true);
IsValidPath("/abc");
IsValidPath("abc");
IsValidPath("abc", true);

And these would return true:

IsValidPath(@"C:\\abc");
IsValidPath(@"F:\FILES\");
IsValidPath(@"C:\\abc.docx\\defg.docx");
IsValidPath(@"C:/abc/defg");
IsValidPath(@"C:\\\//\/\\/\\\/abc/\/\/\/\///\\\//\defg");
IsValidPath(@"C:/abc/def~`!@#$%^&()_-+={[}];',.g");
IsValidPath(@"C:\\\\\abc////////defg");
IsValidPath(@"/abc", true);
IsValidPath(@"\abc", true);

There are plenty of good solutions in here, but as none of then check if the path is rooted in an existing drive here's another one:

private bool IsValidPath(string path)
{
// Check if the path is rooted in a driver
if (path.Length < 3) return false;
Regex driveCheck = new Regex(@"^[a-zA-Z]:\\$");
if (!driveCheck.IsMatch(path.Substring(0, 3))) return false;


// Check if such driver exists
IEnumerable<string> allMachineDrivers = DriveInfo.GetDrives().Select(drive => drive.Name);
if (!allMachineDrivers.Contains(path.Substring(0, 3))) return false;


// Check if the rest of the path is valid
string InvalidFileNameChars = new string(Path.GetInvalidPathChars());
InvalidFileNameChars += @":/?*" + "\"";
Regex containsABadCharacter = new Regex("[" + Regex.Escape(InvalidFileNameChars) + "]");
if (containsABadCharacter.IsMatch(path.Substring(3, path.Length - 3)))
return false;
if (path[path.Length - 1] == '.') return false;


return true;
}

This solution does not take relative paths into account.

this accepts a path that could equate to a valid relative path too

string path = "yourPath";
bool pathIsValid = null;
try
{
Path.GetFullPath(path);
pathIsValid = true;
}
catch
{
pathIsValid = false;
}