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:///
を考えるとそれは、確かに本当に醜いとしても、このソリューションは十分に優れていると思います。