Assembly.CodeBase は有望に見えますが、UNC パスです。
UNC パスではなく、ファイルの uriに近いものであることに注意してください。
これを解決するには、文字列を手動で操作します。真剣に。
SO で見つけられる他のすべての方法を、次のディレクトリ (逐語的に) で試してください。
C:\Test\Space( )(h#)(p%20){[a&],t@,p%,+}.,\Release
これは有効な Windows パスです。(パスにこれらの文字のいずれかが含まれている人もいますが、それらすべてに対して機能する方法が必要ですよね?)
利用可能なコード ベース (必要ありませんLocationよね? ) のプロパティは次のとおりです (.NET 4 を使用する私の Win7 では):
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);
}
より良い解決策を思いつくことができると確信しています。おそらく、CodeBaseそれがローカルパスである場合、プロパティの適切な URL エンコード/デコードを行うソリューションを思いつくことさえできますが、単に削除して実行できることfile:///を考えるとそれは、確かに本当に醜いとしても、このソリューションは十分に優れていると思います。