VSTemplate multi-file template not showing/working - visual-studio

I need to create three files several times in a project, with references to each other by a name convention. VS Item Templates seemed like an easy way to escape the hunt-and-peck copy-pasta-rename headache.
According to the docs it's possible to create a multi-file item template. The built-in VS2022 exporter only allows the selection of one file.
So I exported a single file, tried loading that up in VS2022, and it worked.
I then went on a search, found the aforementioned doc, added my other files, reloaded the template, and now it does not appear in the Add -> New Item menu.
<VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Item">
<TemplateData>
<DefaultName>EfVueMantleMSC.cs</DefaultName>
<Name>EfVueMantleMSC</Name>
<Description>Create Model, Service, and Controller classes for EfVueMantle in one shot</Description>
<ProjectType>CSharp</ProjectType>
<SortOrder>10</SortOrder>
<Icon>__TemplateIcon.ico</Icon>
</TemplateData>
<TemplateContent>
<References />
<ProjectItem SubType="" TargetFileName="$fileinputname$Controller.cs" ReplaceParameters="true">ControllerTemplate.cs</ProjectItem>
<ProjectItem SubType="" TargetFileName="$fileinputname$Model.cs" ReplaceParameters="true">ModelTemplate.cs</ProjectItem>
<ProjectItem SubType="" TargetFileName="$fileinputname$Service.cs" ReplaceParameters="true">ServiceTemplate.cs</ProjectItem>
</TemplateContent>
</VSTemplate>
The .zip folder has all three class files, names matching the above. It's in the right place, I can load/unload single-file templates exported from VS2022 without issue. I've dug through a bunch of Q&A about earlier VS versions with this issue, but everything seems in order.
Is there something obviously wrong? Is there a straightforward way to debug when a template doesn't load, like some sort of log?
Are the MS Docs just lying again?

Related

Using CustomParameter with Visual Studio Multi-Project Template

I would like to be able to create a Multi-Project Template for a solution which contains the following two projects (where the interface should include a reference to the business layer).:
<proj_name>.interface
<proj_name>.business.
Normally, you can include $safeprojectname$, which has:
The name provided by the user in the New Project dialog box
However, as pointed out in the article Build a multi-project visual studio template
The problem here is that within each child template, $safeprojectname$ represents the current project name. There needs to be a way to pass in the root $safeprojectname$ from the parent template.
I'm trying to implement the solution suggested in this SO question VS 2010 Multi-Project Template: Inter-Project References, by using CustomParameters, but am running into trouble.
My Zipped Up Template Directory looks like this:
MultiTemplate.vstemplate
Interface
InterfaceTemplate.vstemplate
MyTemplate.Interface.csproj
Business
BusinessTemplate.vstemplate
MyTemplate.Business.csproj
You can download the Entire Directory, but here are some select snippets
MultiTemplate.vstemplate
<VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="ProjectGroup">
<TemplateData><!--Removed for brevity --></TemplateData>
<TemplateContent>
<CustomParameters>
<CustomParameter Name="$SolutionName$" Value="$safeprojectname$"/>
</CustomParameters>
<ProjectCollection>
<ProjectTemplateLink ProjectName="$safeprojectname$.Interface">
Interface\InterfaceTemplate.vstemplate
</ProjectTemplateLink>
<ProjectTemplateLink ProjectName="$safeprojectname$.Business">
Business\BusinessTemplate.vstemplate
</ProjectTemplateLink>
</ProjectCollection>
</TemplateContent>
</VSTemplate>
Interface\InterfaceTemplate.vstemplate
<VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Project">
<TemplateData><!--Removed for brevity --></TemplateData>
<TemplateContent>
<Project TargetFileName="MyTemplate.Interface.csproj"
File="MyTemplate.Interface.csproj"
ReplaceParameters="true">
</Project>
</TemplateContent>
</VSTemplate>
MyTemplate.Interface.csproj
<ItemGroup>
<ProjectReference Include="..\$SolutionName$.Business\$SolutionName$.Business.csproj">
<Project>{E5511F75-5B9C-4816-B991-E09225661CF4}</Project>
<Name>MyTemplate.Business</Name>
</ProjectReference>
</ItemGroup>
The Problem
When I create a new project, the $SolutionName$ portion of the string does not get replaced. Instead it just stays the same.
Q: How can I properly pass this information from the Multi-Project Template to each of the child templates?
Bonus points if you can figure out how to replace the <name> tag value, as token replacements don't seem to work on it.
Visual Studio 2013 Update 2 finally added a built-in way to do this with ProjectTemplateLink
The CopyParameters attribute will enable child access to all the variables of the parent template, with the prefix of ext_.
You don't even need CustomParameters for this. Change your ProjectTemplateLink to this:
<ProjectTemplateLink ProjectName="$safeprojectname$.Interface" CopyParameters="true">
Interface\InterfaceTemplate.vstemplate
</ProjectTemplateLink>
And then you can achieve your goal in the child .csproj like so:
<ItemGroup>
<ProjectReference Include="..\$ext_safeprojectname$.Business\$ext_safeprojectname$.Business.csproj">
<Project>{E5511F75-5B9C-4816-B991-E09225661CF4}</Project>
<Name>MyTemplate.Business</Name>
</ProjectReference>
</ItemGroup>
Full Disclosure: I am the creator of the below mentioned project.
I solved the issue of sharing information between project templates in a multi-project template be creating an IWizard implementation called GlobalParams. It makes the information from the solution template level available to the child templates that also run the wizard by prefixing ALL solution level parameters with the word global and adding it to the child parameters.
If you used GlobalParams with the above template and the user entered "Test Project", the following would be true:
InterfaceTemplate.vstemplate could access
$safeprojectname$ = Test_Project.Interface
$globalsafeprojectname$ = Test_Project
BusinessTemplate.vstemplate could access
$safeprojectname$ = Test_Project.Business
$globalsafeprojectname$ = Test_Project
The above is an example of the safe project name but all parameters from the solution template are passed to child template See the GlobalParams Documentation for more information.

How to define a template for adding multiple files to a project?

My new project is my first look at WPF MVVM and WCF and I like it but it seems like I am creating a lot of files, always in the same basic setup and structure.
I am wondering if anyone has a way of defining some kind of folder/project structure as an input and automatically creating the various POCOs, views, models, service classes and interfaces, perhaps with some kind of consistent prefix for the file name.
Then the developer can just go in and cut the code to get their data.
I saw this, which is sort of the right idea:
http://www.codeproject.com/Articles/16515/Creating-a-Custom-Tool-to-Generate-Multiple-Files
A colleague also suggested a batch file might be worth investigating. Open to all ideas, thanks for your help.
UPDATE //
This would take place after the project was created. So the folders and projects are already in place but you want to add the necessary files for an end-to-end service call and presentation.
You can use Visual Studio's Item Template not only to add a single file, but also to add multiple items and sort them in your project folder structure:
If you create an item template with VS, via File -> Export Template, you get a zipped folder. You can unzip it and add several files, for example until it looks like this:
You can then modify the file named 'MyTemplate'. The according file for the above example looks like this:
<VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Item">
<TemplateData>
<DefaultName>Enter Module Name here</DefaultName>
<Name>INCA Module</Name>
<Description>Creates all files for a module - Add this item at project root level only!</Description>
<ProjectType>CSharp</ProjectType>
<SortOrder>10</SortOrder>
<Icon>__TemplateIcon.ico</Icon>
</TemplateData>
<TemplateContent>
<References />
<ProjectItem SubType="Code" TargetFileName="Models/$fileinputname$.cs" ReplaceParameters="true">ElementModel.cs</ProjectItem>
<ProjectItem SubType="Code" TargetFileName="ViewModels$fileinputname$ViewModel.cs" ReplaceParameters="true">ElementViewModel.cs</ProjectItem>
<ProjectItem SubType="Designer" TargetFileName="$fileinputname$View.xaml" ReplaceParameters="true">View.xaml</ProjectItem>
<ProjectItem SubType="Code" TargetFileName="$fileinputname$View.xaml.cs" ReplaceParameters="true">View.xaml.cs</ProjectItem>
<ProjectItem SubType="Designer" TargetFileName="Metadata/$fileinputname$Metadata.xaml" ReplaceParameters="true">Metadata.xaml</ProjectItem>
<ProjectItem SubType="Code" TargetFileName="Metadata/$fileinputname$Metadata.xaml.cs" ReplaceParameters="true">Metadata.xaml.cs</ProjectItem>
</TemplateContent>
</VSTemplate>
I think, what happens here is quite self explanatory.
It is very helpful to use template parameters:
MSDN on Template Parameters
Then just zip the whole thing again and place it in the folder User/Visual Studio xy/Templates. Note, that templates are exported to the folder called MyExportedTemplates.
I remember vs2010 can export your project to template, so you can encapsulate your folders or data in project and export to template.
Atfer you finished that, you can create your custom project from template.

VSX: Custom project types

I'm trying to create a project template that works with VS2010 Standard/Pro/Ultimate, as well as Integrated Shell.
I've got the VS2010 Std part working, but for the life of me I can't get it to work w/ Int Shell - probably because my install doesn't have any CSharp projects.
After googling for what seems all day, I stumbled upon IronPython's vstemplate files, which look like this:
<VSTemplate Version="2.0.0" Type="Project" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">
<TemplateData>
<Name>Python Application</Name>
<Description>A project for creating a command-line application</Description>
<Icon>__TemplateIcon.ico</Icon>
<ProjectType>Python</ProjectType>
<SortOrder>50</SortOrder>
<NumberOfParentCategoriesToRollUp>2</NumberOfParentCategoriesToRollUp>
<CreateNewFolder>false</CreateNewFolder>
<DefaultName>PythonApplication</DefaultName>
<ProvideDefaultName>true</ProvideDefaultName>
</TemplateData>
<TemplateContent>
<Project File="PythonApp.pyproj" ReplaceParameters="true">
<ProjectItem ReplaceParameters="true" OpenInEditor="true" TargetFileName="$safeprojectname$.py">Program.py</ProjectItem>
</Project>
</TemplateContent>
</VSTemplate>
These templates work with all versions and have a different ProjectType than the ones mentioned on MSDN: ProjectType = Python. How did they do this? If I use something other than CSharp/Web/VisualBasic, my project type gets sent down the drain.
Thanks;
I didn't get deep into the problem you are describing but I guess these 2 tips will help you to address the issue. In short you should care about ProjectType property for your custom ProjectNode class, and also ensure you have specified it somewhere in VSX attrubutes and in your custom .template file (I don't remember where I did that exactly). So there are those links I mentioned:
Walkthrough: Part 1 - Creating a Basic Project System (search
for 'ProjectType' and 'ProjectGuid' words onthe page)
Root Node of Custom Project Type in 'New Project' Dialog box
(also look at 'Related Topics' from the right of the page)
Hope that helps!

Visual Studio Item Template with Wizard

I am looking for a sample on how to create an item template with Wizard in Visual Studio 2010.
My requirement is when the user selects Add Item, I want to show a dialog where the user enters some input parameters. Then on pressing OK in the form we generate an XML file which we want to add to the project.
Thanks
I'd recommend you get the vsix featured in this link
http://blogs.msdn.com/b/visualstudio/archive/2010/03/04/creating-and-sharing-project-item-templates.aspx
and rename it as a zip file and open it up to start with. however the xml in the Item Templates themselves aren't all that complicated. Looking at one I just generated with the tool for a classic asp file.
<VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Item">
<TemplateData>
<DefaultName>Classic ASP</DefaultName>
<Name>Classic ASP</Name>
<Description>Adds script tag import ref</Description>
<ProjectType>Web</ProjectType>
<ProjectSubType>VisualBasic</ProjectSubType>
<SortOrder>10</SortOrder>
<Icon>__TemplateIcon.ico</Icon>
</TemplateData>
<TemplateContent>
<References />
<ProjectItem TargetFileName="$fileinputname$.asp" ReplaceParameters="true">ClassicASP.asp</ProjectItem>
</TemplateContent>
</VSTemplate>

VS2010 Project Template + VMSDK

For the life of me, I can't get my DSL project to be exported as a template, other than the default ItemTemplate (as in Add New Item)
Does anyone happen to have a summary of what has to be done to be able to create a new project? VSTemplate follows. Have tried adding the zip to the VSIX as Content (ProjTemplate) to no avail.
<!--DSL Tools Language Template-->
<VSTemplate Version="3.0.0" Type="Item" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<TemplateData>
<Name Package="{602c1894-d640-407a-a311-aca9d5ab7a5c}" ID="103"/>
<Description Package="{602c1894-d640-407a-a311-aca9d5ab7a5c}" ID="102"/>
<Icon Package="{602c1894-d640-407a-a311-aca9d5ab7a5c}" ID="201" />
<ProjectType>CSharp</ProjectType>
<SortOrder>360</SortOrder>
<DefaultName>FlowDsl.mhf</DefaultName>
</TemplateData>
<TemplateContent>
<ProjectItem TargetFileName="$fileinputname$.mhf">mhf.mhf</ProjectItem>
<ProjectItem TargetFileName="$fileinputname$.mhf.diagram">mhf.diagram</ProjectItem>
</TemplateContent>
</VSTemplate>
Thanks;
It sounds like you want a project template, correct? For starters, the Type attribute on the VSTemplate element should be Type="Project" instead of Type="Item". Additionally, project templates need to have a <Project> element (usually a csproj/vbproj file) in the <TemplateContent> to use as a starter project.
I would suggest creating a C# or VB project with an instance of your DSL as a project item (and structuring the project as you would want your template). Then, try using the Export Template Wizard to create a VSIX with your project template.
If you want to further customize and control what is in the template, check out this blog post which describes how to manually author and package your templates.

Resources