アプリケーションルートに関連する画像フォルダーがあるアプリケーションで作業しています。この相対パスを [プロパティ] -> [設定] デザイナーなどで指定できるようにしたいと考えています。"\画像\". 私が直面している問題は、Environment.CurrentDirectory が OpenFileDialog を介して変更され、相対パスが正しい場所に解決されない場合です。設定ファイルで、現在のディレクトリではなくアプリケーション ディレクトリから常に開始することを意味するパスを指定する方法はありますか? アプリケーション パスを相対パスの先頭にいつでも動的に連結できることはわかっていますが、Settings プロパティはそれ自体で解決できるようにしたいと考えています。
6 に答える
私の知る限り、このタイプのパス解決を可能にする組み込み機能はありません。最善の方法は、アプリケーションを実行するディレクトリを動的に決定し、それにイメージ パスを連結することです。Environment.CurrentDirectory
言及した理由で特に使用したくない-現在のディレクトリは、この状況では常に正しいとは限りません。
実行中のアセンブリの場所を見つけるために私が見つけた最も安全なコードは次のとおりです。
public string ExecutingAssemblyPath()
{
Assembly actualAssembly = Assembly.GetEntryAssembly();
if (this.actualAssembly == null)
{
actualAssembly = Assembly.GetCallingAssembly();
}
return actualAssembly.Location;
}
Application.ExecutablePath をお探しですか? これにより、アプリケーションの実行可能ファイルの場所がわかり、実行可能ファイルの名前が削除され、パスが追加されます。
そのために、次の 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\
.
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()
により、実行中のコードを含むアセンブリの場所が得られます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 プロパティを呼び出す関数を実装し、文字列の無関係な部分を切り取ることです。