Ответ 1
Вот так, просто держи свой хак.
В простой Win32 для этого есть вспомогательная функция PathAddBackslash. Просто совместите с разделителем каталогов: проверьте Path.DirectorySeparatorChar
и Path.AltDirectorySeparatorChar
вместо жесткого кода \
.
Что-то вроде этого (обратите внимание, что серьезной проверки ошибок нет):
string PathAddBackslash(string path)
{
// They're always one character but EndsWith is shorter than
// array style access to last path character. Change this
// if performance are a (measured) issue.
string separator1 = Path.DirectorySeparatorChar.ToString();
string separator2 = Path.AltDirectorySeparatorChar.ToString();
// Trailing white spaces are always ignored but folders may have
// leading spaces. It unusual but it may happen. If it an issue
// then just replace TrimEnd() with Trim(). Tnx Paul Groke to point this out.
path = path.TrimEnd();
// Argument is always a directory name then if there is one
// of allowed separators then I have nothing to do.
if (path.EndsWith(separator1) || path.EndsWith(separator2))
return path;
// If there is the "alt" separator then I add a trailing one.
// Note that URI format (file://drive:\path\filename.ext) is
// not supported in most .NET I/O functions then we don't support it
// here too. If you have to then simply revert this check:
// if (path.Contains(separator1))
// return path + separator1;
//
// return path + separator2;
if (path.Contains(separator2))
return path + separator2;
// If there is not an "alt" separator I add a "normal" one.
// It means path may be with normal one or it has not any separator
// (for example if it just a directory name). In this case I
// default to normal as users expect.
return path + separator1;
}
Почему так много кода? Первичный, потому что если пользователь вводит /windows/system32
, вы не хотите получать /windows/system32\
, но /windows/system32/
, дьявол находится в деталях...
Чтобы собрать все вместе в более удобной самоочевидной форме:
string PathAddBackslash(string path)
{
if (path == null)
throw new ArgumentNullException(nameof(path));
path = path.TrimEnd();
if (PathEndsWithDirectorySeparator())
return path;
return path + GetDirectorySeparatorUsedInPath();
bool PathEndsWithDirectorySeparator()
{
char lastChar = path.Last();
return lastChar == Path.DirectorySeparatorChar
|| lastChar == Path.AltDirectorySeparatorChar;
}
char GetDirectorySeparatorUsedInPath()
{
if (path.Contains(Path.DirectorySeparatorChar))
return Path.DirectorySeparatorChar;
return Path.AltDirectorySeparatorChar;
}
}
В этом втором примере формат URI file://
, по-видимому, корректно обрабатывается, но не обманывается внешностью: он не (например, с ошибкой file://path
). Правильная вещь - снова сделать то, что делают другие функции .NET I/O: не обрабатывать этот формат (и, возможно, исключать).
В качестве альтернативы вы всегда можете импортировать функцию Win32:
[DllImport("shlwapi.dll",
EntryPoint = "PathAddBackslashW",
SetLastError = True,
CharSet = CharSet.Unicode)]
static extern IntPtr PathAddBackslash(
[MarshalAs(UnmanagedType.LPTStr)]StringBuilder lpszPath);