I've gotten into the habit of always putting a trailing slash at the end of my folder paths and this appears to be the norm (e.g. Visual Studio macros such as $(ProjectDir) always have a trailing slash). In addition, when I'm appending a relative path to the end of an existing folder path I always put a leading slash just in case the folder path that is passed to me doesn't have a trailing slash (e.g. Windows batch: set FULL_FILE_PATH=%FOLDER_PATH%\path\to\some\file).
That being said, I tend to end up with paths that look like this C:\path\to\folder\\path\to\some\file.txt (note the two backslashes in a row). In addition, since I'm using dev\src dev\include and dev\script folder structure (where .vcxproj files and similar go in the script folder), most of my paths append a relative path with up-levels to at the end of some macro like $(ProjectDir) (e.g. Include dir = $(ProjectDir)\..\include\).
In the following code somePath02Uri and somePath03Uri return (what I believe to be) incorrect results:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DotNet45SystemUriTest
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("We will now test the System.Uri constructor:\n");
// Output from Console.WriteLine is in the comment on the same line
String somePath01 = "C:\\some\\common\\..\\include\\";
Console.WriteLine("somePath01 = " + somePath01); // somePath01 = C:\some\common\..\include\
Uri somePath01Uri = new Uri(somePath01);
Console.WriteLine("somePath01Uri = " + somePath01Uri.ToString()); // somePath01Uri = file:///C:/some/include/
Console.WriteLine();
String somePath02 = "C:\\some\\common\\\\..\\include\\";
Console.WriteLine("somePath02 = " + somePath02); // somePath02 = C:\some\common\\..\include\
Uri somePath02Uri = new Uri(somePath02);
Console.WriteLine("somePath02Uri = " + somePath02Uri.ToString()); // somePath02Uri = file:///C:/some/common/include/
Console.WriteLine();
String somePath03 = "C:\\some\\common\\\\\\..\\include\\";
Console.WriteLine("somePath03 = " + somePath03); // somePath03 = C:\some\common\\\..\include\
Uri somePath03Uri = new Uri(somePath03);
Console.WriteLine("somePath03Uri = " + somePath03Uri.ToString()); // somePath03Uri = file:///C:/some/common//include/
Console.WriteLine();
}
}
}
Why does System.Uri interpret two slashes in a row as folder?
Almost forgot: If you do encounter this a quick and dirty solution is to remove the two backslashes in a row from the string before creating the Uri object. I did this by adding .Replace("\\\\", "\\")
:
String somePath02 = "C:\\some\\common\\\\..\\include\\";
Console.WriteLine("somePath02 = " + somePath02); // somePath02 = C:\some\common\\..\include\
Uri somePath02Uri = new Uri(somePath02.Replace("\\\\", "\\"));
Console.WriteLine("somePath02Uri = " + somePath02Uri.ToString()); // somePath02Uri = file:///C:/some/include/