Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VS2010 MPF: Populating 'Add->New Item...' list for a custom project

I've created a custom language package, which extends ProjectPackage. I can create the new project correctly. I would like to be able to add new source files to the project by using the Add->New Item... (Ctrl+Shift+A) menu item. However, when I click this at the moment the list of available templates is empty. I would like to add my own custom template to the menu of available templates for this project type. Is there some documentation for accomplishing this? The only mentions I have seen have been registry hacks, but there has to be a way to do the programmatically I would think.

Is there a particular method I can override to populate the list? Do I really need to make a template, or can I just show the 'template name', 'icon' and provide the correct file extension (the files should be empty when created, so I think a template is largely wasted on what I want to do).

Here's the path I've been traveling down thus far. I figured I could set my project type and GUID in my custom .vproj file (.vproj is the file extension that my custom project is registered under). I thought I could quickly create a item template with the same ProjectType as my .vproj file.

<VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Item">
  <TemplateData>
    <Icon>VerilogSource.ico</Icon>
    <DefaultName>module.v</DefaultName>
    <Name>Basic Verilog Module</Name>
    <Description>
      A basic Verilog module for quickly adding new files to the project.
    </Description>
    <ProjectType>VerilogProject</ProjectType>
  </TemplateData>
  <TemplateContent>
    <ProjectItem TargetFileName="$fileinputname$.v"
        ReplaceParameters="true">module.v</ProjectItem>
  </TemplateContent>
</VSTemplate>

Alas, this template does not show up at all, even though I've included it in VSIX and copied it to the output directory. If I put this template in the same folder as my .vproj, it will appear as a template for creating a new project (wrong!) and still won't appear in my new items list. This could all derive from the fact that I do not use a VSTemplate for creating my project. Instead I use [ProvideProjectFactoryAttribute] to let VS2010 know where my vproj file is, and it will use the vproj file (which I guess you could call a template, but it isn't a VSTemplate, it is a Project) to base the new project off of.

This is where I am at so far, and I'm continuing to try new things. I'm hoping someone might have the answer I am looking for. Thanks,

Giawa

like image 489
Giawa Avatar asked Jul 26 '11 22:07

Giawa


1 Answers

After a lot of reading and work, here's my answer:

Use vstemplate files for your project and items, and compile them as vstemplate (do not copy to output, do not include with VSIX, contrary to what the Microsoft Walkthrough suggests). The compiler will package each item and project template into their own zip file. Now, you need to tell the vsixmanifest where those files are. The default directories for projects and items are ProjectTemplates and ItemTemplates, respectively. Add them to your vsixmanifest like so:

  <Content>
    <VsPackage>|%CurrentProject%;PkgdefProjectOutputGroup|</VsPackage>
    <ProjectTemplate>ProjectTemplates</ProjectTemplate>
    <ItemTemplate>ItemTemplates</ItemTemplate>
  </Content>

Now, you must also add some properties to your .csproj file that your vsix package is built in. These properties can probably be added via some convoluted method, but the easiest is just to drop them directly in the .csproj file.

  <PropertyGroup>
    <GetVsixSourceItemsDependsOn>$(GetVsixSourceItemsDependsOn);GetVsixTemplateItems</GetVsixSourceItemsDependsOn>
  </PropertyGroup>
  <Target Name="GetVsixTemplateItems" DependsOnTargets="ZipProjects;ZipItems">
    <ItemGroup>
      <VSIXSourceItem Include="@(IntermediateZipItem)">
        <VSIXSubPath>ItemTemplates\%(IntermediateZipItem.Language)\%(IntermediateZipItem.OutputSubPath)\%(IntermediateZipItem.Culture)</VSIXSubPath>
      </VSIXSourceItem>
      <VSIXSourceItem Include="@(IntermediateZipProject)">
        <VSIXSubPath>ProjectTemplates\%(IntermediateZipProject.Language)\%(IntermediateZipProject.OutputSubPath)\%(IntermediateZipProject.Culture)</VSIXSubPath>
      </VSIXSourceItem>
    </ItemGroup>
  </Target>

This will now include your zip files into your project, and with any luck, you'll now have projects and items that are linked correctly together.

Luckily, there is quite a bit of documentation out there for item/project templates. It just took me a while to realize that is the correct way to go. Good luck,

Giawa

like image 78
Giawa Avatar answered Oct 12 '22 01:10

Giawa