Относительный путь настроек .NET - PullRequest
0 голосов
/ 12 ноября 2008

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

Ответы [ 6 ]

1 голос
/ 12 ноября 2008

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

1 голос
/ 12 ноября 2008

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

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

public string ExecutingAssemblyPath()
{
   Assembly actualAssembly = Assembly.GetEntryAssembly();
   if (this.actualAssembly == null)
   {
      actualAssembly = Assembly.GetCallingAssembly();
   }
   return actualAssembly.Location;
}
0 голосов
/ 08 июня 2011

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

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

0 голосов
/ 04 октября 2009

Я предлагаю вам использовать Assembly.CodeBase, как показано ниже:

public static string RealAssemblyFilePath()
{
   string dllPath=Assembly.GetExecutingAssembly().CodeBase.Substring(8);
   return dllPath;
}

Вы можете попробовать Application.ExecutablePath . Но вам нужно сделать ссылку на System.Windows.Forms. Это может не быть хорошей идеей, если вы хотите, чтобы ваша библиотека классов держалась подальше от форм и UI.

Вы можете попробовать Assembly.GetExecutingAssembly (). Расположение . Но если каким-либо образом вы выполняете «Теневое копирование» перед запуском приложения (например, поведение NUnit по умолчанию), то это свойство вернет вам местоположение теневой копии, а не реальное физическое местоположение.

Лучший способ - реализовать функцию, которая вызывает свойство CodeBase объекта Assembly и отсекает несущественную часть строки.

0 голосов
/ 28 января 2009

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

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

Для Windows и консольных приложений очевидным способом является:

Application.StartupPath
0 голосов
/ 12 ноября 2008

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.

...