URIs are not local paths.
It's easy to forget that even though a local filesystem path ("C:\MyDir\MyFile.dll") can be represented as a Uri (file://C:/MyDir/MyFile.dll), these two entities are different, and have different rules for validations.
The problem du jour, the reason I even got into this, was a simple piece of code that was to set the Current Directory to that of the currently executing assembly:
Uri assemblyPath = new Uri(Assembly.GetExecutingAssembly().CodeBase);
if (assemblyPath.Scheme == Uri.UriSchemeFile)
{
string dllPath = Path.GetDirectoryName(assemblyPath.PathAndQuery);
Directory.SetCurrentDirectory(dllPath);
}
The CodeBase property of the Assembly class gives us the path as a Uri, since assemblies can also be loaded from HTTP paths.
This worked fine on most machines, but seemed to break on one. The reason? His path was a valid file system path, but not a valid URI:
G:\C#_Projects\MyFile.dll
The problem is that the # sign is a valid path, but a delimiter for URIs - it marks the start of a URI fragment, like a named anchor in an HTML file. Getting PathAndQuery for the URI simply returned "G:/C", and dropped everything after the #.
The simple solution - rather than attempting to join the URI's Fragment and Path together, is to remove the scheme (file://) from the beginning and consider that a local path:
Uri
assemblyPath = new Uri("file://c:/c#_path/file.dll");if (assemblyPath.Scheme == Uri.UriSchemeFile)
{
// This gives us "c:/c#_path/file.dll".
string dllPath = assemblyPath.OriginalString.Replace(assemblyPath.Scheme + Uri.SchemeDelimiter, "");
// This gives us "c:\\c#_path".
dllPath = Path.GetDirectoryName(dllPath);
Directory.SetCurrentDirectory(dllPath);
}
1 Comment
Comments have been disabled for this content.
DevareattyVaH said
nice, really nice!