3 решения:
лучший сценарий, где вы на 100% уверены, то вызывающий процесс будет иметь полный доступ к файловой системе. CAVEAT: разрешение на коробке производства может быть сложно
public static string PathCombineAndCanonicalize1(string path1, string path2)
{
string combined = Path.Combine(path1, path2);
combined = Path.GetFullPath(combined);
return combined;
}
Но мы не всегда свободны. Часто вам нужно выполнить строчную арифметику без разрешения. Для этого есть естественный призыв. CAVEAT: прибегает к нативной вызову
public static string PathCombineAndCanonicalize2(string path1, string path2)
{
string combined = Path.Combine(path1, path2);
StringBuilder sb = new StringBuilder(Math.Max(260, 2 * combined.Length));
PathCanonicalize(sb, combined);
return sb.ToString();
}
[DllImport("shlwapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool PathCanonicalize([Out] StringBuilder dst, string src);
Третья стратегия обмануть CLR. Path.GetFullPath() отлично работает на фиктивном пути, поэтому просто убедитесь, что вы всегда даете ему один. Что вы можете сделать, это поменять корень с фальшивым путем UNC, позвоните GetFullPath(), а затем поменять реальную обратно в CAVEAT:. это может потребовать трудно продать в обзоре кода
public static string PathCombineAndCanonicalize3(string path1, string path2)
{
string originalRoot = string.Empty;
if (Path.IsPathRooted(path1))
{
originalRoot = Path.GetPathRoot(path1);
path1 = path1.Substring(originalRoot.Length);
}
string fakeRoot = @"\\thiscantbe\real\";
string combined = Path.Combine(fakeRoot, path1, path2);
combined = Path.GetFullPath(combined);
combined = combined.Substring(fakeRoot.Length);
combined = Path.Combine(originalRoot, combined);
return combined;
}