2008-11-12 5 views
0

Я работаю над приложением, где у меня есть папка с изображениями относительно моего корня приложения. Я хочу, чтобы указать этот относительный путь в конструкторе «Свойства ->», например. "\Изображений\". Проблема, с которой я сталкиваюсь, в случаях, когда Environment.CurrentDirectory изменяется с помощью OpenFileDialog, относительный путь не разрешается в нужном месте. Есть ли способ указать в файле настроек путь, который будет означать, что он всегда начинается с каталога приложения, а не из текущего каталога? Я знаю, что всегда могу динамически конкатенировать путь приложения к началу относительного пути, но я бы хотел, чтобы мое свойство настроек могло само решить..NET Settings Относительный путь

ответ

1

Насколько я знаю, нет встроенных функций, которые позволят разрешение этого типа. Ваш лучший вариант - динамически определять приложения, выполняющие каталог, и конкатенировать с ним путь к изображениям. Вы не хотите использовать Environment.CurrentDirectory специально по причинам, о которых вы упомянули - текущий каталог может не всегда быть правильным для этой ситуации.

Самый безопасный код, который я нашел, чтобы найти выполняющую расположение сборки заключается в следующем:

public string ExecutingAssemblyPath() 
{ 
    Assembly actualAssembly = Assembly.GetEntryAssembly(); 
    if (this.actualAssembly == null) 
    { 
     actualAssembly = Assembly.GetCallingAssembly(); 
    } 
    return actualAssembly.Location; 
} 
+0

У вас есть `this.`, который выглядит как ошибка - и при каких обстоятельствах вам действительно нужен этот оператор` if`? BTW, имейте в виду, что `GetCallingAssembly` может делать удивительные вещи, если концептуальный вызывающий абонент получает встроенную среду выполнения. По этой причине я избегаю этого метода и просто смотрю сборку вместо «Тип». Это, по крайней мере, безопасно. – 2011-06-08 15:01:05

0

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 .

1

Вы ищете Application.ExecutablePath? Это должно сообщить вам, где исполняемый файл приложения, удалить имя исполняемого файла и затем добавить к нему свой путь.

+0

Это будет работать, только если это приложение Windows Forms. Он также возвращает путь к исполняемому файлу, который запустил приложение, включая имя исполняемого файла, поэтому вам нужно удалить только часть пути. – 2008-11-12 14:33:14

0

Это похоже на работу в обоих WinForms и ASP.NET (дает путь к конфигурационный файл):

new System.IO.FileInfo(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile).Directory; 

для приложений Windows, и консоли, очевидный способ заключается в использовании:

Application.StartupPath 
0

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 и отрубает ненужную часть строки.

0

Я использую следующие два метода, чтобы помочь с этим:

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\.