118

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?

InteXX
  • 5,804
  • 5
  • 33
  • 54
Tobias Boschek
  • 1,972
  • 2
  • 17
  • 21
  • possible duplicate of [How check if given string is legal (allowed) file name under Windows?](http://stackoverflow.com/questions/62771/how-check-if-given-string-is-legal-allowed-file-name-under-windows) – nawfal Jun 05 '13 at 11:43

12 Answers12

61

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.
    
Ivan Ivković
  • 305
  • 1
  • 9
abatishchev
  • 92,232
  • 78
  • 284
  • 421
  • This sounds very promising... I take a closer look at it! I'll drop a line after I have evaluated if the method serves my purpose! Thanks abatishchev – Tobias Boschek Jun 01 '11 at 12:45
  • 10
    This returns false for `@"foo\bar\baz"`, which is a perfectly valid relative path... – Thomas Levesque Oct 18 '12 at 08:26
  • 5
    Thomas: What UriKind did you specify? You can use Absolute, Relative or AbsoluteOrRelative. – Dan Gøran Lunde Feb 09 '13 at 10:38
  • 2
    Even with UriKind as Relative or AbsoluteOrRelative it didn't work for relative paths like Thomas mentioned. I ended up using Patko's answer instead & it works for my purposes. – JohnnyM Apr 16 '14 at 20:15
  • 1
    I found that a path such as \\computerName\Dir Name With Spaces\fileName throws an exception when using IsWellFormedUriString (contrary to my initial expectation), because the spaces aren't properly encoded. I found that I could just use the Uri(string) constructor as my validation, thereby, not having to properly encode the string before validating. – quintessential5 Jul 15 '14 at 23:37
  • Does not work with a simple path like "\\myserver\mypath" with releative or absolute uri kind. – AH. Sep 15 '15 at 12:14
  • 1
    This doesn't work for all this exemples. https://msdn.microsoft.com/en-us/library/system.uri.iswellformeduristring(v=vs.110).aspx The documentation say : "The string is considered poorly formed, causing the method to return false, if any of the following conditions occur : The string is not correctly escaped. http://www.contoso.com/path???/file name The string is an absolute Uri that represents an implicit file Uri. c:\\directory\filename …" – Xav987 Jan 19 '17 at 15:46
  • 4
    Returns false on a perfectly fine file path. – Evgeni Petrov Mar 06 '17 at 15:55
  • Answer says `IsWellFormedUriString` but links to `IsWellFormedOriginalString`. Though the page seems to indicate the former has special behavior with .Net 4.5+, I believe the main difference is that one is static and one is an instance method. – Chris Apr 26 '18 at 14:05
29

Or use the FileInfo as suggested in In C# check that filename is possibly valid (not that it exists).

Community
  • 1
  • 1
Patko
  • 4,227
  • 1
  • 30
  • 27
  • Using the solution posted by "LamdaComplex", on the same thread, seems more accurate : http://stackoverflow.com/a/11636052/2546739 – Xav987 Jan 19 '17 at 16:28
8

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);
Dao Seeker
  • 165
  • 1
  • 8
6
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;
}
Alex Jolig
  • 10,688
  • 19
  • 103
  • 148
  • 1
    Creating a folder is a nasty side effect for a boolean that you think is going to just check a string for you. – HackSlash Nov 30 '20 at 22:36
4

You can try this code:

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

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

Nimrod
  • 123
  • 1
  • 8
2

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.

Gark Garcia
  • 310
  • 2
  • 12
1

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

Martijn
  • 11,183
  • 10
  • 46
  • 92
1

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

Umesh CHILAKA
  • 1,446
  • 14
  • 25
  • 3
    This isn't entirely valid. "C:\new.folder" is valid while "C:\newfolder." is not. '.' is a valid character for a paths/filenames, but not at the end of the uri. – claudekennilol Mar 07 '13 at 16:13
-2
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;
}
krlzlx
  • 5,476
  • 14
  • 44
  • 51
-3

Directory.Exists?

markpsmith
  • 4,776
  • 2
  • 28
  • 58
-4

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

-6

Just Simply Use

if (System.IO.Directory.Exists(path))
{
    ...
}
Mahdi Astanei
  • 1,825
  • 1
  • 14
  • 26