Assembly.CodeBase выглядит многообещающе, но это UNC-путь:
Обратите внимание, что это что-то, приближенное к файлу uri , , а не и UNC-путь .
Вы решаете эту проблему вручную. Серьезно.
Попробуйте все другие методы, которые вы можете найти в SO, со следующим каталогом (дословно):
C:\Test\Space( )(h#)(p%20){[a&],t@,p%,+}.,\Release
Это допустимый, хотя и несколько необычный путь Windows. (У некоторых людей будет любой из этих символов в этих путях, и вы хотите, чтобы ваш метод работал для всех из них, верно?)
Доступная база кода ( нам не нужны Location
, верно? ) свойства тогда (на моем Win7 с .NET 4):
assembly.CodeBase -> file:///C:/Test/Space( )(h#)(p%20){[a&],t@,p%,+}.,/Release
assembly.EscapedCodeBase -> file:///C:/Test/Space(%20)(h%23)(p%20)%7B%5Ba%26%5D,t@,p%,+%7D.,/Release
Вы заметите:
CodeBase
вообще не экранирован, это просто обычный локальный путь с префиксом file:///
и заменены обратные слеши. Таким образом, не не работает, чтобы передать это System.Uri
.
EscapedCodeBase
не полностью экранирован (я не знаю, является ли это ошибкой или это недостаток схемы URI ):
- Обратите внимание, как символ пробела (
) переводится в %20
- но последовательность
%20
также переводится в %20
! (проценты %
вообще не экранированы)
- Никто не может восстановить оригинал из этой искаженной формы!
Для локальных файлов (И это действительно все, что мне нужно для CodeBase
, потому что, если файл не локальный, вы, вероятно, все равно захотите использовать .Location
, мне подходит следующее (обратите внимание, что это не самая красивая либо:
public static string GetAssemblyFullPath(Assembly assembly)
{
string codeBasePseudoUrl = assembly.CodeBase; // "pseudo" because it is not properly escaped
if (codeBasePseudoUrl != null) {
const string filePrefix3 = @"file:///";
if (codeBasePseudoUrl.StartsWith(filePrefix3)) {
string sPath = codeBasePseudoUrl.Substring(filePrefix3.Length);
string bsPath = sPath.Replace('/', '\\');
Console.WriteLine("bsPath: " + bsPath);
string fp = Path.GetFullPath(bsPath);
Console.WriteLine("fp: " + fp);
return fp;
}
}
System.Diagnostics.Debug.Assert(false, "CodeBase evaluation failed! - Using Location as fallback.");
return Path.GetFullPath(assembly.Location);
}
Я уверен, что можно придумать лучшие решения, возможно, можно даже придумать решение, которое делает правильное URL-декодирование / свойство свойства CodeBase
, если это локальный путь, но, учитывая, что можно просто удалить от file:///
и покончим с этим, я бы сказал, что это решение достаточно хорошо, если конечно действительно ужасно.