Both the GuidancePackageSolution.vstemplate file in GAT and SoftwareFactorySolutionCSharp.vstemplate / SoftwareFactorySolutionVB.vstemplate files in Clarius SFT use substitution parameters to specify the ProjectName attribute of ProjectTemplateLink elements - this does not appear to be supported by the visual studio template mechanism.
<TemplateContent>
<ProjectCollection>
<ProjectTemplateLink ProjectName="$PackageName$Installer">Projects\GuidancePackageInstaller\GuidancePackageInstaller.vstemplate</ProjectTemplateLink>
<ProjectTemplateLink ProjectName="$PackageName$">Projects\GuidancePackage\GuidancePackage.vstemplate</ProjectTemplateLink>
</ProjectCollection>
</TemplateContent>
This produces folders in windows explorer called (literally) $PackageName$ and $PackageName$Installer !
To help me learn about GAX etc., I have been writing my own Software Factory creator (i.e. a scaled down version of what SFT is trying to achieve) and have worked around this problem.
My solution .vstemplate file looks like the following:
<VSTemplate
Version="2.0"
Type="ProjectGroup"
xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">
<TemplateData>
<Name>Software Factory (C#)</Name>
<Description>Creates a solution for developing a Software Factory in C#</Description>
<ProjectType>CSharp</ProjectType>
<SortOrder>90</SortOrder>
<CreateNewFolder>true</CreateNewFolder>
<DefaultName>SoftwareFactory</DefaultName>
<ProvideDefaultName>true</ProvideDefaultName>
<Icon>SoftwareFactorySolution.ico</Icon>
</TemplateData>
<TemplateContent>
<!-- Unfortunately the ProjectTemplateLink element does not support substitution parameters for the project name
so we will have to generate the package / installer / setup projects using a Recipe -->
<ProjectCollection/>
</TemplateContent>
<WizardExtension>
<Assembly>Microsoft.Practices.RecipeFramework.VisualStudio, Version=1.0.60429.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Assembly>
<FullClassName>Microsoft.Practices.RecipeFramework.VisualStudio.Templates.UnfoldTemplate</FullClassName>
</WizardExtension>
<WizardData>
<Template xmlns="http://schemas.microsoft.com/pag/gax-template"
SchemaVersion="1.0"
Recipe="CreateSoftwareFactory">
<References>
</References>
</Template>
</WizardData>
</VSTemplate>
My CreateSoftwareFactory recipe contains actions which use the UnfoldTemplateAction action to manually unfold the project templates to the correct folders.
Here isa sample:
<Arguments>
<Argument Name="PackageName">
<Converter Type="Microsoft.Practices.RecipeFramework.Library.Converters.RegexMatchStringConverter, Microsoft.Practices.RecipeFramework.Library"
Expression="[a-zA-Z][a-zA-Z_0-9]*(\.[a-zA-Z][a-zA-Z_0-9]*)*"/>
<ValueProvider Type="ExpressionEvaluatorValueProvider" Expression="$(safeprojectname)"/>
</Argument>
<Argument Name="PackageCaption">
<ValueProvider Type="ExpressionEvaluatorValueProvider" Expression="$(safeprojectname)"/>
</Argument>
<Argument Name="PackageNamespace">
<Converter Type="Microsoft.Practices.RecipeFramework.Library.Converters.NamespaceStringConverter, Microsoft.Practices.RecipeFramework.Library"/>
</Argument>
<Argument Name="PackageDescription" />
<Argument Name="Author" Type="System.String">
<ValueProvider Type="DefaultAuthorValueProvider" />
</Argument>
<Argument Name="SolutionPath">
<ValueProvider Type="SolutionPathProvider" />
</Argument>
<Argument Name="SolutionArgument" Type="EnvDTE.Solution, EnvDTE, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Converter Type="SolutionConverter" />
<ValueProvider Type="ExpressionEvaluatorValueProvider"Expression="/" />
</Argument>
<Argument Name="ProjectFolder">
<ValueProvider Type="ExpressionEvaluatorValueProvider" Expression="$(SolutionPath)\$(PackageName)">
<MonitorArgument Name="PackageName"/>
</ValueProvider>
</Argument>
<Argument Name="InstallerProjectName">
<ValueProvider Type="ExpressionEvaluatorValueProvider" Expression="$(PackageName)Installer">
<MonitorArgument Name="PackageName"/>
</ValueProvider>
</Argument>
<Argument Name="InstallerProjectFolder">
<ValueProvider Type="ExpressionEvaluatorValueProvider" Expression="$(SolutionPath)\$(InstallerProjectName)">
<MonitorArgument Name="InstallerProjectName"/>
</ValueProvider>
</Argument>
</Arguments>
...
<Actions>
<!-- Trigger the unfolding of the Package / Installer .vstemplate files (which we didn't do
in the SoftwareFactorySolution.vstemplate file because we couldn't dynamically assign the project names there) -->
<Action Name="UnfoldPackageProjectTemplate"
Type="UnfoldTemplateAction"
Template="Solutions\Projects\SoftwareFactoryCSharp\SoftwareFactoryCSharp.vstemplate">
<Input Name="Root" RecipeArgument="SolutionArgument" />
<Input Name="DestinationFolder" RecipeArgument="ProjectFolder" />
<Input Name="ItemName" RecipeArgument="PackageName" />
<Output Name="NewItem" />
</Action>
<Action Name="UnfoldInstallerProjectTemplate"
Type="UnfoldTemplateAction"
Template="Solutions\Projects\SoftwareFactoryInstallerCSharp\SoftwareFactoryInstallerCSharp.vstemplate">
<Input Name="Root" RecipeArgument="SolutionArgument" />
<Input Name="DestinationFolder" RecipeArgument="InstallerProjectFolder" />
<Input Name="ItemName" RecipeArgument="InstallerProjectName" />
<Output Name="NewItem" />
</Action>
...
</Actions>
I hope this helps people who've had similar problems with solution templates ...
P.S. Perhaps the next releases of GAT / SFT could address this issue ?