.NET設定の相対パス
-
08-07-2019 - |
質問
アプリケーションルートに関連する画像フォルダがあるアプリケーションで作業しています。プロパティでこの相対パスを指定できるようにしたい->設定デザイナー。 " \ Images \"。私が遭遇している問題は、OpenFileDialogを介してEnvironment.CurrentDirectoryが変更された場合に、相対パスが正しい場所に解決されないことです。現在のディレクトリではなく、常にアプリケーションディレクトリから開始することを意味するパスを設定ファイルで指定する方法はありますか?アプリケーションパスを相対パスの前にいつでも動的に連結できることは知っていますが、Settingsプロパティがそれ自体を解決できるようにしたいと思います。
解決
私が知る限り、このタイプのパス解決を可能にする組み込み機能はありません。最良のオプションは、ディレクトリを実行するアプリケーションを動的に決定し、それに画像パスを連結することです。あなたが言及した理由のために Environment.CurrentDirectory
を使用したくありません-現在のディレクトリはこの状況に対して常に正しいとは限りません。
実行中のアセンブリの場所を見つけるために見つけた最も安全なコードは次のとおりです。
public string ExecutingAssemblyPath()
{
Assembly actualAssembly = Assembly.GetEntryAssembly();
if (this.actualAssembly == null)
{
actualAssembly = Assembly.GetCallingAssembly();
}
return actualAssembly.Location;
}
他のヒント
Application.ExecutablePathを探していますか?これにより、アプリケーションの実行可能ファイルの場所がわかり、実行可能ファイル名を削除してから、パスを追加する必要があります。
2つのオプション:
- この設定を使用するコードは、現在実行中のアセンブリのディレクトリに対して設定を解決できます。
- 実行中のアセンブリに対して文字列としてシリアル化され、現在実行中のアセンブリのディレクトリに対して解決するフルパスのアクセサを持つ独自のタイプを作成できます。
コードサンプル:
string absolutePath = Settings.Default.ImagePath;
if(!Path.IsPathRooted(absolutePath))
{
string root = Assembly.GetEntryAssembly().Location;
root = Path.GetDirectoryName(root);
absolutePath = Path.Combine(root, absolutePath);
}
このコードの良い点は、設定で完全修飾パスまたは相対パスを使用できることです。パスを別のアセンブリからの相対パスにする必要がある場合は、使用するアセンブリの場所を変更できます- GetExecutingAssembly()
は、実行中のコードを含むアセンブリの場所を提供し、< code> GetCallingAssembly()は、オプション2を使用する場合に適しています。
これは、WinFormsとASP.NETの両方で機能するようです(構成ファイルへのパスを提供します):
new System.IO.FileInfo(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile).Directory;
Windowsおよびコンソールアプリケーションの場合、明白な方法は以下を使用することです
Application.StartupPath
お勧めします以下に示すようにAssembly.CodeBaseを使用します。
public static string RealAssemblyFilePath()
{
string dllPath=Assembly.GetExecutingAssembly().CodeBase.Substring(8);
return dllPath;
}
Application.ExecutablePath 。ただし、System.Windows.Formsを参照する必要があります。クラスライブラリでフォームやUIを避けたい場合、これは良い考えではありません。
Assembly.GetExecutingAssembly()。Location 。しかし、どういうわけか、「シャドウコピー」を行うと、アプリケーションを実行する前(デフォルトのNUnitの動作など)、このプロパティは実際の物理的な場所ではなく、シャドウコピーの場所を返します。
最良の方法は、AssemblyオブジェクトのCodeBaseプロパティを呼び出す関数を実装し、文字列の無関係な部分を切り捨てることです。
次の2つの方法を使用して、これを支援します。
public static IEnumerable<DirectoryInfo> ParentDirs(this DirectoryInfo dir) {
while (dir != null) {
yield return dir;
dir = dir.Parent;
}
}
public static DirectoryInfo FindDataDir(string relpath, Assembly assembly) {
return new FileInfo((assembly).Location)
.Directory.ParentDirs()
.Select(dir => Path.Combine(dir.FullName + @"\", relpath))
.Where(Directory.Exists)
.Select(path => new DirectoryInfo(path))
.FirstOrDefault();
}
さまざまなビルドスクリプトが bin \ x64 \ Release \ NonsensePath \
などのディレクトリに物を貼り付けてしまう場合に、開発中に使いやすくするために親ディレクトリを見る理由。