Как вы получаете каталог решения в C # (VS 2008) в коде? - PullRequest
10 голосов
/ 17 июня 2010

Здесь возникла досадная проблема. У меня есть приложение NHibernate / Forms, я работаю через SVN. Я сделал некоторые из своих собственных элементов управления, но когда я перетаскиваю их (или просматриваю некоторые редакторы форм, где я уже перетаскивал) на некоторые другие мои элементы управления, Visual Studio решает, что нужно выполнить часть написанного мной кода, включая часть, которая ищет hibernate.cfg.xml.

Я понятия не имею, почему это так, но (иногда!), Когда он выполняет код во время загрузки моей формы или перетаскивает его, переключает текущий каталог в C: \ program files \ vs 9.0 \ common7 \ ide, а затем nhibernate выдает исключение, что он не может найти hibernate.cfg.xml, потому что я ищу это в относительном пути.

Теперь я не хочу жестко кодировать местоположение hibernate.cfg.xml или просто копировать hibernate.cfg.xml в каталог ide (который будет работать). Мне нужно решение, которое получает каталог решений, в то время как текущий каталог - common7 \ ide. Что-то, что позволит кому-то просматривать мои формы в конструкторе при новой проверке в произвольном каталоге на произвольной машине. И нет, я не собираюсь загружать элементы управления в коде. У меня так много элементов управления внутри элементов управления, что выстраивать все без него - кошмар.

Я пробовал событие предварительной сборки, в результате которого был создан файл с каталогом решений, но, конечно, как я могу найти это в common7 \ ide? Все файлы проектов должны быть в каталоге решений из-за svn.

Спасибо за вашу помощь, ребята, я уже потратил несколько часов, напрасно пытаясь справиться с этим.

ОБНОВЛЕНИЕ: я установил hibernate.cfg как встроенный ресурс. Для каждой конфигурации я просто делаю новую конфигурацию сборки, отладку, выпуск, XYZ. В большинстве случаев я рекомендую встраивать любые файлы, от которых вы зависите, для запуска программы. Это значительно упрощает создание установщика.

Ответы [ 6 ]

18 голосов
/ 23 августа 2010

Возможно, это немного поздно, но я нашел решение по адресу http://www.tek -tips.com / viewthread.cfm? Qid = 1226891 & page = 164 . Поскольку я использую Visual Studio 2010, я внес несколько небольших изменений. Вы должны ссылаться на EnvDTE и EnvDTE100 (EnvDTE90 для VS2008),

string solutionDirectory = ((EnvDTE.DTE)System.Runtime
                                              .InteropServices
                                              .Marshal
                                              .GetActiveObject("VisualStudio.DTE.10.0"))
                                   .Solution
                                   .FullName;
solutionDirectory = System.IO.Path.GetDirectoryName(solutionDirectory);

Конечно, я использовал VisualStudio.DTE.10.0, вам, вероятно, следует использовать VisualStudio.DTE.9.0.

Удачи!

9 голосов
/ 20 декабря 2013

Я наконец понял это. Это будет работать для любой версии Visual Studio, не зависит от EnvDTE и решает оригинальную проблему, представленную здесь.

  1. В настройках проекта в разделе «События сборки» добавьте следующую «Командную строку события перед сборкой»:

    echo $(SolutionDir) > ..\..\solutionpath.txt
    
  2. Создайте проект один раз. Файл будет создан в корне вашего проекта.

  3. В обозревателе решений нажмите «Показать все файлы» и «Обновить»

  4. Добавьте solutionpath.txt к вашему решению

  5. Щелкните правой кнопкой мыши solutionpath.txt, выберите Свойства. Измените действие сборки на «Встроенный ресурс»

  6. Используйте следующий код, чтобы получить путь решения.

        string assemblyname = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
        string path = "";
        using (var stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(assemblyname + ".solutionpath.txt"))
        {
            using (var sr = new StreamReader(stream))
            {
                path = sr.ReadToEnd().Trim();
            }
        }
    

Поскольку это событие перед сборкой, файл не должен существовать до начала сборки, поэтому он совместим с контролем версий и не имеет каких-либо очевидных проблем.

3 голосов
/ 17 июня 2010

Обновление : К сожалению, я не знаю, как получить папку вашего решения во время разработки.Итак, технически я не отвечаю на ваш вопрос, просто предлагаю потенциальный обходной путь.

Вы можете проверить, находится ли ваш контроль в DesignMode, и если это так, вы можете использовать Assembly.GetExecutingAssembly(), чтобы получить Assembly для вашего элемента управления и определения местоположения, из которого он был загружен.

Обратите внимание, что есть некоторые предупреждения со значением свойства DesignTime, а именно, если вы разрабатываете свой элемент управления или если вы разрабатываете форму, содержащую ваш элемент управления, он вернётся правильно как true, но если вы разрабатываете форму, которая содержит элемент управления, содержащий ваш элемент управления, он будет возвращать false.

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

2 голосов
/ 27 октября 2011

Я закончил встраивание файла конфигурации. Так как программа автоматически обновляется независимо от конфигурационного файла, я могу отказаться от показа его пользователям.

2 голосов
/ 17 июня 2010

Похоже, вам просто нужно кодировать лучший путь к файлу конфигурации.

Если вы делаете что-то вроде этого:

configPath =  Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "\\PathToCFG");

вы не должны ошибаться, когда Windows меняет текущий каталог на вас.

Редактировать: Возможно, у вас возникла проблема с процессом размещения Visual Studio . Вы можете отключить это? В свойствах проекта \ debug установлен флажок.

1 голос
/ 29 декабря 2018

Я опаздываю, и я понятия не имею, работает ли это в VS2008, но для VS2015 самой простой вещью, которую я мог подумать, было создание шаблона t4. Вот содержимое:

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".generated.cs" #>
namespace MyNamespace
{
    public static class BuildVariables
    {
        public static readonly string SolutionDir = <#= QuotedString(Host.ResolveAssemblyReference(@"$(SolutionDir)")) #>;
    }
}
<#+
public string QuotedString(string value)
{
    if (value == null)
    {
        return "null";
    }

    return "@\"" + value.Replace("\"", "\"\"") + "\"";
}
#>

Это создает класс, который имеет именно то, что нужно. Два предупреждения, которые у меня есть для этого, должны быть уверены, что проигнорировали его из-за контроля версий, и остерегайтесь, копируете ли вы свое решение куда-нибудь еще. К сожалению, создание шаблонов t4 как части автоматизированного процесса сборки все еще является сложной проблемой в 2018 году.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...