Ответ 1
string origAssemblyLocation = Assembly.GetExecutingAssembly().CodeBase;
В MSDN:
Свойство Assembly.CodeBase
Получает местоположение сборки как указанный первоначально
У меня есть этот код для загрузки файла конфигурации и чтения всех значений, и он отлично работает при запуске приложения, но, конечно, не работает в городе команды, потому что базовый каталог appdomain - это то, где запущена сборка script (psake). Я знаю, что я могу сменить каталог в dir build перед выполнением тестов, но я подумал, что лучше делать загрузку файла конфигурации в любое время независимо.
XDocument.Load(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, cfgFile));
Есть ли другой способ получить "BaseDirectory", который действительно работает все время? Я пробовал и ниже, и с теми же результатами:
string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
XDocument.Load(Path.Combine(path, cfgFile));
РЕДАКТИРОВАТЬ 1 Проблема заключается в следующем. Мой базовый каталог решений - "C:\Project", все скомпилированные файлы копируются в "C:\Project\build". Теперь в сборке psake script у меня есть следующий код:
task Test -depends PrepareTests {
try {
#$old = pwd
#cd $build_dir
&$mspec $mspec_projects --teamcity
#cd $old
}
catch {
&echo "Error starting test runner"
Exit 1;
}
}
Как вы можете видеть, я прокомментировал изменение каталогов, что делает BaseDirectory местом сборки файла/решения вместо каталога сборки независимо от того, как я пытаюсь получить к нему доступ. Какой-то запутанный, если вы спросите меня.
UPDATE Мне очень нравится знать, можно ли получить каталог сборки независимо от того, в какой директории находится приложение, которое запустило домен приложения. Как?
string origAssemblyLocation = Assembly.GetExecutingAssembly().CodeBase;
В MSDN:
Свойство Assembly.CodeBase
Получает местоположение сборки как указанный первоначально
Различные способы получения базового каталога
AppDomain.CurrentDomain.BaseDirectory
Directory.GetCurrentDirectory()
//не гарантируется работа над мобильным приложением
Environment.CurrentDirectory
//это вызывает Directory.GetCurrentDirectory()
this.GetType().Assembly.Location
//Assembly.location
Application.StartupPath
//для приложений форм Windows
Application.ExecutablePath
//тот же, что и Application.StartupPath
Итак, это звучит/выглядит так, будто вы пытаетесь получить файл конфигурации для сборки. Следующее должно выполнить эту задачу, обратившись к свойству "Местоположение" сборки и используя ее для извлечения пути конфигурации:
static string GetConfigFileByType(Type type)
{
Configuration config =
ConfigurationManager.OpenExeConfiguration(type.Assembly.Location);
if (config.HasFile)
return config.FilePath;
throw new FileNotFoundException();
}
Ваш вопрос немного неясен. Я не знаю, действительно ли это то, что вы хотите.
Обычно я использую AppDomain.CurrentDomain.BaseDirectory
Альтернативы
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
Environment.CurrentDirectory
попробуйте следующее:
Module[] modules = Assembly.GetExecutingAssembly().GetModules();
return Path.GetDirectoryName(modules[0].FullyQualifiedName);
Вы пытались получить имя_файла текущего процесса MainModule?
System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName
Или GetEntryAssembly()?
System.Reflection.Assembly.GetEntryAssembly().Location
Мне нравится настраивать мои классы - например, они получают имя папки в качестве параметра в своем конструкторе. Это позволяет тестировать различные файлы конфигурации.
В тестовом коде мы используем:
TestContext.TestDeploymentDir
Это папка testrun, в которой все сборки для тестового запуска копируются вместе с элементами тестового развертывания. Мы "разворачиваем" наши файлы конфигурации unit test в папку тестового запуска - это может быть указано в диалоговом окне testrunconfig в visual studio.
Для нашего производственного кода мы передаем
Assembly.GetExecutingAssembly().Location
для конструктора, который работает для нас.
как насчет:
Application.StartupPath;