如果Path包含“#”,则System.Uri无法提供正确的AbsolutePath和LocalPath

时间:2009-05-22 06:27:01

标签: c# .net

我有C#代码尝试使用以下代码行获取执行程序集的LocalPath

Uri uri = new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath;

这段代码适用于各种路径。它开始失败,给出了正确的AbsolutePathLocalpath,因为正在执行的程序集路径中包含一个#。

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报告此问题?

3 个答案:

答案 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;

此问题已多次报告,但MS坚持CodeBase设计herehereherehere的方式。

答案 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