$SpecificSolutionName$ всегда пусто. Как я могу узнать, создает ли пользователь новый каталог решений или нет?
В Visual Studio 2017, создавая проект шаблона проекта C# с интерфейсом IWizard, я выскакиваю пользовательское диалоговое окно, но не могу определить, установили ли они ранее флажок "Создать каталог для решения". Мне нужно знать это, еще находясь в интерфейсной функции RunStarted(), до того, как будет сгенерирован объект Project (другими словами, я не могу использовать project.DTE.Solution).
Замечательная документация Microsoft гласит, что я могу просто посмотреть на $ SpecificSolutionName $, но она всегда для меня пуста.
Между тем, другие вопросы Stackru либо относятся к многопроектным шаблонам, либо просто не имеют ответа. Моя конкретная проблема - простой шаблон с одним проектом.
Я также пробовал $SolutionName$. После нескольких утомительных дней утомительного Google, я сдался и должен был выдумать вещи. Было бы неплохо, если бы мне не приходилось угадывать название ожидаемой папки решения, если оно есть. Хуже того, чтобы определить, является ли папка решения " действительно ли вообще существует " новой или нет, я сравниваю даты ее создания. Вещи начинают достигать критической массы хакерских обходных путей.
Вопрос: Как найти имя папки решения или, по крайней мере, выбрал ли пользователь создание новой папки решения внутри RunStarted() мастера шаблона проекта?
2 ответа
Я узнал, что могу просто "Присоединить к процессу... " временный экземпляр VS и отладить его. Поэтому я должен взглянуть на объект replacementsDictionary.
Вопреки тому, что говорят все документы, на самом деле требуется параметр шаблона:
$SpecifiedSolutionName$
... а не "SpecificSolutionName".
Это половина раскрытой тайны, но не позволяйте этому волновать вас. SpecifiedSolutionName также не делает то, что говорят документы.
С https://docs.microsoft.com/en-us/visualstudio/ide/template-parameters:
Если флажок "создать каталог решения" не установлен, SpecificSolutionName [sic] будет пустым.
Нету. Если "создать каталог решений" не отмечен, $SpecifiedSolutionName$ содержит все, что находится в $ projectname $.
Этого было бы достаточно для нас, если бы не тот факт, что по умолчанию поведение каталога решения и каталога проекта совпадает. Но так как это обычное явление, значение $SpecifiedSolutionName$ не может сказать нам, создал ли пользователь новый каталог решений или нет.
Так что я до сих пор не вижу ничего, что напрямую сообщало бы о том, отмечал ли пользователь этот флажок или нет. Однако есть некоторая логика, через которую вы можете перейти, благодаря другому параметру шаблона, который называется $solutiondirectory$.
Который тоже сломан.
Если пользователь выберет "Создать каталог для решения", то $solutiondirectory$ - это каталог, в котором будет находиться файл решения. Если пользователь снимает флажок "Создать каталог для решения", то $solutiondirectory$ - это каталог, в котором находится каталог, в котором будет находиться файл решения, и, следовательно, он, вероятно, находится выше файловой системы, чем вы заботитесь.
То, что $solutiondirectory$ reports на самом деле является просто $destinationdirectory$\..\. То есть каталог над каталогом, в котором будет храниться файл проекта. Не имеет значения, была ли отмечена галочка "Создать каталог для решения", параметр $solutiondirectory$ заботится о файле и каталоге проекта, а не о решении.
Итак, вернемся к вопросу, как мы узнаем, если пользователь поставил галочку "Создать каталог для решения", когда решение и проект могут иметь одно и то же имя?
В этом случае почти два правонарушения почти оправдывают себя. Сравните $SpecifiedSolutionName$ с последним элементом пути в $solutiondirectory$. Если они отличаются, пользователь определенно снял флажок "Создать каталог для решения". (Потому что первое будет именем проекта, а второе будет тем, что у файловой системы чуть выше.)
Если они одинаковы, пользователь, вероятно, поставил галочку в этом поле. Но есть еще одна вещь, которую следует учитывать. Возможно, по какой-то причине каталог выше всего этого также имеет то же имя, что и каталог проекта и / или решения. Пользователи могут быть такими странными. Я не знаю надежного способа объяснить эту ситуацию (возможно, есть еще каталоги с тем же именем), поэтому я просто оставляю это как нечто, о чем нужно знать.
Вот что работает в VS2019:
Когда пользователь устанавливает флажок "Поместить решение и проект в тот же каталог", $ specifiedsolutionname $ пусто, а $ solutiondirectory $ содержит путь к корневой папке, в которой размещается все, что связано с новым решением. Если этот флажок не установлен, $ specifiedsolutionname $ содержит "имя решения", указанное пользователем (которое является именем подпапки, созданной в корневой папке решения, и где размещаются проекты), а $ destinationdirectory $ содержит правильный путь к корневой папке решения.
HTH
Наконец, для мультипроектного решения вот что заставило меня работать:
Шаблон уровня решения (мультипроект):-
<TemplateContent>
<ProjectCollection>
<ProjectTemplateLink ProjectName="$safeprojectname$.WebApp">
WebApp\MyTemplate.vstemplate
</ProjectTemplateLink> .....
Изменения уровня кода
namespace $safeprojectname$
Благодаря 1-му шагу имя проекта теперь включает имя решения. На уровне проекта пространство имен и имя сборки в идеале должны быть такими, чтобы не требовалось разделять их.
Позвольте мне знать, если это помогает