我有C#代码尝试使用以下代码行获取执行程序集的LocalPath
:
Uri uri = new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath;
这段代码适用于各种路径。它开始失败,给出了正确的AbsolutePath
和Localpath
,因为正在执行的程序集路径中包含一个#。
Assembly.GetExecutingAssembly().CodeBase
提供"C:\c#\ExcelAddin1.1.0\GSRExcelPlugin\bin\Debug\Common.dll"
但是新的Uri(Assembly.GetExecutingAssembly()。CodeBase).LocalPath给出“C:\ c”,而它应该给出“C:\ c#\ ExcelAddin1.1.0 \ GSRExcelPlugin \ bin \ Debug \”。
我需要处理某些东西,或者使用Uri类的方式有什么问题吗?
如果这是.net框架问题,我应该如何向Microsoft报告此问题?
答案 0 :(得分:7)
System.IO.FileInfo logger = new System.IO.FileInfo(Path.Combine(Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().EscapedCodeBase).LocalPath), "settings.config"));
使用EscapedCodeBase而不是CodeBase解决了这个问题。我已经意识到这已经处理好了,直到我偶然发现它。:)
答案 1 :(得分:2)
Uri
类的行为符合预期。 #
不是网址的有效部分。 Imo这是CodeBase
属性的问题。它返回一个字符串unescaping特殊字符,使其几乎不可靠。您的选择是:
1)始终使用EscapedCodeBase
属性。
var uri = new Uri(Assembly.GetExecutingAssembly().EscapedCodeBase).LocalPath;
2)或者如果你真的需要处理CodeBase
属性(如果这是唯一选项),请自行获取转义部分。
var x = new Uri(Assembly.GetExecutingAssembly().CodeBase);
var uri = x.LocalPath + Uri.UnescapeDataString(x.Fragment).Replace('/', '\\');
3)对于已加载程序集的文件位置,最简单的方法是使用Location
属性。
var uri = Assembly.GetExecutingAssembly().Location;
答案 2 :(得分:1)
我假设URI函数正在消除锐化#
之后的所有内容,因为它认为它是一个锚点。
URI用于识别互联网上的资源,因此您的#
字符在任何URI中间都是非法字符。
以这个问题为例,标题是
如果路径包含“#”,则System.Uri无法提供正确的AbsolutePath和LocalPath
但是网址末尾的“#”已被删除
system-uri-fails-to-give-correct-absolutepath-and-localpath-if-the-path-contains
为什么还需要将其转换为URI。这3个console.writelines之间唯一的区别是前两个以File:///
为前缀
Console.WriteLine(Assembly.GetExecutingAssembly().CodeBase); // 1
Uri uri = new Uri(Assembly.GetExecutingAssembly().CodeBase);
Console.WriteLine(uri); // 2
Console.WriteLine(uri.LocalPath); // 3