System.Uri не дает правильных AbsolutePath и LocalPath, если Path содержит "#",

У меня есть код С#, который пытается получить 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:\С#\ExcelAddin1.1.0\GSRExcelPlugin\bin\Debug \".

Есть ли что-то, что мне нужно для обработки, или что-то не так, как используется класс Uri?

Если это проблема с картой .net, как мне сообщить об этой проблеме Microsoft?

Ответ 1

System.IO.FileInfo logger = new System.IO.FileInfo(Path.Combine(Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().EscapedCodeBase).LocalPath), "settings.config"));

Использование EscapedCodeBase вместо CodeBase решает проблему. Я понимаю, что это уже было обработано до тех пор, пока я не наткнулся на него.:)

Ответ 2

Я предполагаю, что функции URI отбрасывают все после резкого #, потому что он считает его привязкой.

URI предназначены для идентификации ресурсов в Интернете, поэтому ваш символ # будет незаконным символом в середине любого URI.

Возьмите даже этот вопрос, например, Title

System.Uri не дает правильные Абсолютные и Локальные Патчи, если Путь содержит "#"

но в конце URL-адреса "#" удалено

system-uri-fails-to-give-correct-absolutepath-and-localpath-if-the-path-contains

Почему вам все равно нужно преобразовать его в URI. Единственная разница между этими тремя консольными сценариями заключается в том, что первые два имеют префикс File:///

Console.WriteLine(Assembly.GetExecutingAssembly().CodeBase);  // 1
Uri uri = new Uri(Assembly.GetExecutingAssembly().CodeBase);
Console.WriteLine(uri);                                       // 2
Console.WriteLine(uri.LocalPath);                             // 3

Ответ 3

Класс Uri ведет себя как ожидалось. # не является действительной частью URL-адреса. Имо это проблема с свойством 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 разработан здесь, здесь, здесь и здесь.