Я работаю над приложением, где у меня есть папка с изображениями относительно моего корня приложения. Я хочу, чтобы указать этот относительный путь в конструкторе «Свойства ->», например. "\Изображений\". Проблема, с которой я сталкиваюсь, в случаях, когда Environment.CurrentDirectory изменяется с помощью OpenFileDialog, относительный путь не разрешается в нужном месте. Есть ли способ указать в файле настроек путь, который будет означать, что он всегда начинается с каталога приложения, а не из текущего каталога? Я знаю, что всегда могу динамически конкатенировать путь приложения к началу относительного пути, но я бы хотел, чтобы мое свойство настроек могло само решить..NET Settings Относительный путь
ответ
Насколько я знаю, нет встроенных функций, которые позволят разрешение этого типа. Ваш лучший вариант - динамически определять приложения, выполняющие каталог, и конкатенировать с ним путь к изображениям. Вы не хотите использовать Environment.CurrentDirectory
специально по причинам, о которых вы упомянули - текущий каталог может не всегда быть правильным для этой ситуации.
Самый безопасный код, который я нашел, чтобы найти выполняющую расположение сборки заключается в следующем:
public string ExecutingAssemblyPath()
{
Assembly actualAssembly = Assembly.GetEntryAssembly();
if (this.actualAssembly == null)
{
actualAssembly = Assembly.GetCallingAssembly();
}
return actualAssembly.Location;
}
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 .
Вы ищете Application.ExecutablePath? Это должно сообщить вам, где исполняемый файл приложения, удалить имя исполняемого файла и затем добавить к нему свой путь.
Это будет работать, только если это приложение Windows Forms. Он также возвращает путь к исполняемому файлу, который запустил приложение, включая имя исполняемого файла, поэтому вам нужно удалить только часть пути. – 2008-11-12 14:33:14
Это похоже на работу в обоих WinForms и ASP.NET (дает путь к конфигурационный файл):
new System.IO.FileInfo(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile).Directory;
для приложений Windows, и консоли, очевидный способ заключается в использовании:
Application.StartupPath
I suggest you использовать Assembly.CodeBase, как показано ниже:
public static string RealAssemblyFilePath()
{
string dllPath=Assembly.GetExecutingAssembly().CodeBase.Substring(8);
return dllPath;
}
Вы можете попробовать Application.ExecutablePath. Но вам нужно сделать ссылку на System.Windows.Forms. Это не может быть хорошей идеей, если вы хотите, чтобы ваша библиотека классов избегала форм и элементов пользовательского интерфейса.
Вы можете попробовать Assembly.GetExecutingAssembly().Location. Но если вы каким-то образом выполняете «Теневую копию» перед запуском своего приложения (например, по умолчанию по умолчанию NUnit), это свойство вернет вам местоположение теневой копии, а не реальное физическое местоположение.
Лучший способ - реализовать функцию, которая вызывает свойство CodeBase объекта Assembly и отрубает ненужную часть строки.
Я использую следующие два метода, чтобы помочь с этим:
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\
.
У вас есть `this.`, который выглядит как ошибка - и при каких обстоятельствах вам действительно нужен этот оператор` if`? BTW, имейте в виду, что `GetCallingAssembly` может делать удивительные вещи, если концептуальный вызывающий абонент получает встроенную среду выполнения. По этой причине я избегаю этого метода и просто смотрю сборку вместо «Тип». Это, по крайней мере, безопасно. – 2011-06-08 15:01:05