Deploy assembly containing IWizard for project template with VSIX - visual-studio-2010

I have created an extension for VS 2010 that deploys a project template. The project template uses a custom wizard (in a specific assembly) that is called when I create a new project based on this template.
I want to package the assembly containing the wizard within the VSIX, so that it gets deployed somewhere the template can find it (I know GAC is not an option with VSIX).
Basically if I deploy the assembly to the GAC, install the VSIX and then create the project the wizard is invoked successfully.
If I do the same without deploying the assembly first, the project templates does not find the assembly when I create the project.
My question is: how to deploy a project template and the assembly it needs using a VSIX package?
Thank you for your help
EDIT: I changed the VSIX Sub Path of the wizard assembly reference to "ProjectTemplates" in both the installer project and updated the vsixmanifest content assembly reference accordingly. It seems to work now.

You don't need to get your assembly containing the IWizard implementation in the GAC. You can simply declare it in your extension.vsixmanifest file as an Assembly element in the Content section.
Unfortunately, this doesn't appear to be documented well anywhere.
The only tricky part is making sure that the AssemblyName attribute has the correct value.

I had no luck with the Assembly element technique to work, so in case anyone else runs into the same problem, here's another solution.
Visual Studio looks for wizard DLLs using the BindingPaths registry key. If you add the folder containing your DLL in a subkey of BindingPaths, then Visual Studio will find your DLL.
To do this from a VSIX, create a .pkgdef file in your VSIX project. Set its Include in VSIX property to True, and paste the following text into it:
[$RootKey$\BindingPaths\{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}]
"$PackageFolder$"=""
(where the Xs represent the package GUID, though I suspect any GUID will do).

This works for me:
[$RootKey$\BindingPaths\{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}]
"$PackageFolder$"=""
But assembly element doesn't work.

Related

How do you deploy a Visual Studio project template that has a wizard?

I have a Project Template that I want to make available to people that I work with. How should project templtes (and item templates) be deployed? According to MSDN on this page (https://msdn.microsoft.com/en-us/library/xkh1wxd8.aspx) you should use a vsix package, but template wizards must be installed to the GAC and a vsix package cannot do that.
It seems that you don't need the GAC after all. See:
Using IWizard in an item template without installing assembly in GAC?
Using IWizard in an item template without installing assembly in GAC?

Unable To Reference Wizard Assembly in VSIX Deployed Template

I am trying to create a VISX extension for Visual Studio 2010 that contains a few project templates. These templates aren't very complex, but I want to expose some additional configuration for them during creation via a wizard. I have successfully set up my VISX package to deploy the templates to the directory structure I want in VS2010, but as soon as I try to configure and run a wizard, I receive an error when I create the template along the lines of:
Error: this template attempted to load component assembly
'My.Assembly, Version 1.0.0.0, Culture=neutral, PublicKeyToken=...
My current configuration is as follows:
All the projects live in the same solution.
The VISX project includes project references to the project containing the wizards and to each template.
Each template is built from a project template template (...confusing terminology).
They are added through the .vsixmanifest designer as content, referencing the projects.
Each .vstemplate file has a WizardExtension element pointing to the IWizard implementation and containing assembly.
The wizard assembly is signed.
The .vstemplate files point to their wizards like this:
<WizardExtension>
<Assembly>My.Assembly, Version=1.0.0.1, Culture=neutral, PublicKeyToken=a494da9e6e53f845, Custom=null
</Assembly>
<FullClassName>My.Assembly.Wizard</FullClassName>
</WizardExtension>
This, as far as I can tell, is how I'm supposed to do it. What exactly is going wrong? It looks like it can't find the assembly. Are there any other steps I need to take in order to get the assembly visible to the templates? The assembly is deployed to the extension folder when it is installed (I verified this), so it is at least making it out. Is there something special I need to do to the .vstemplate files to tell them to look in the extensions folder vs the GAC? Did I just miss something?
Note that I have found several pages on the internet stating that I have to GAC the assembly manually or with a script. However, few had my exact scenario (Project template templates being referenced by a VISX project, most examples are using a regular project exported via the project template wizard and having their packages dumped into the VISX folder structure). The only one I found that matched my scenario was an example from Microsoft. I tried to match that, but alas it still does not work. I tried relocating the project I downloaded to reference in this question but I cannot find it again, though.
Using scripts is how we've done this before, but I want to try and make things a little cleaner using VISX packages. I would like to avoid this, but if it's mandatory to script the VISX to install the template to GAC, I can do that.
When deploy the wizard based project template by VSIX Extension, it is better to use Short-Named assembly in .vstemplate. This can avoid the GAC deployment.
In your case, it should be:
<WizardExtension>
<Assembly>My.Assembly</Assembly>
<FullClassName>My.Assembly.Wizard</FullClassName>
</WizardExtension>
I am using VS2015 and faced this issue on and off. When I started building VSIX project with Wizard implementation, everything worked fine for sometime (4-6 weeks) and suddenly it stopped working. After a couple of weeks it would start working again and stop working without notice. Took me long time to find a workaround (still don't know why it suddenly stops).
This is how my VSIX project is built
I have VSIX project, project template and Wizard implementation in
the same solution.
VSIX and Wizard implementation are in the same project.
Added VSIX project dll and project template as Assets in VSIX project source.extension.vsixmanifest.
Project template *.vstemplate has Wizard section which refers to VSIX project with strong name:
<<<<<<<<<<<<<<<<<<<<<<
<WizardExtension>
<Assembly>Test.Template.TemplateInstallerWizard, Version=1.0.0.0, Culture=neutral, PublicKeyToken=30ab381f68dc4f5e</Assembly>
<FullClassName>Test.Template.TemplateInstallerWizard.WizardImplementation</FullClassName>
</WizardExtension>
None of these worked for me
Uninstalled extension from VS regular instance via Tools->Extensions
and Updates..
Uninstalled extension from VS experimental instance by
launching VS exp instance from VS2015 command prompt as Administrator:
devenv.exe /rootsuffix exp
and then uninstalling the extension via Tools->Extensions and Updates..
Using short named assembly as explained by #Ethan Wu.
Installing templates via this command from VS2015 command prompt launched as administrator:
devenv /installvstemplates
Rebooting VS2015, my machine several times during this process.
This is what worked for me (thanks to #Ethan Wu)
Remove certificate from VSIX project.
Remove strong name from Project Template *.vstemplate
file
<WizardExtension>
<Assembly>Test.Template.TemplateInstallerWizard, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null</Assembly>
<FullClassName>Test.Template.TemplateInstallerWizard.WizardImplementation
Clean and build the project.
Remove extension from VS regular instance and close VS2015 (not
absolutely required)
Install the extension.
Open new VS2015 instance and try to create the project with
wizard.
Couple of things to help debug
When VSIX project is build, in bin\debug folder a file is
created -extension.vsixmanifest which has the assets type.
Look for Asset Type="Microsoft.VisualStudio.Assembly":
AssemblyName value is what is expected in project template's
*.vstemplate WizardExtension section - they should match exactly.
After installing extension, go to VS2015 extension location on
local box:
%appdata%\..\Local\Microsoft\VisualStudio\14.0\Extensions\<some_temp_folder>
open extension.vsixmanifest to ensure that Asset
Type="Microsoft.VisualStudio.Assembly" AssemblyName value is
correctly populated. If required, you can change this value and
restart VS2015 to make this in effect.
Hope this will help someone and save tons of time as there is very little help on Wizard and custom project templates.
Thanks,
RDV
I run into the same problem, but mine came to light when I updated the AssemblyVersion of my wizard project. I checked and the versions in the manifest files matched as they should.
I simply went into C:\Users\Albert\AppData\Local\Microsoft\VisualStudio\16.0_c340331cExp\Extensions, found my extension and deleted it there. Now it works again.
(Note that I did find a few others since I've since changed the company name etc, in the AssemblyInfo file, so it could be the old ones laying around that also caused this)

Copy Files to Project Folder with Visual Studio Project Template

I'm making a custom Visual Studio Project Template for a CSharp project and was wondering if there was a way to copy a dll from the template zip file to the new project file without including the dll in the project files?
The idea is that the project references the dll, but I just dont want the developers to care about the assembly.
What I did was, created new template wizard i.e. by implementing IWizard interface.
This article(http://msdn.microsoft.com/en-us/magazine/cc188697.aspx) will help you to get started with custom wizard.
Then in the RunStarted() method you will be able to get path to the current template like this
Path.GetDirectoryName((string)customParams[0])
Also you can get the path where the project is created using below code
replacementsDictionary["$destinationdirectory$"]
Once you have these values, do a normal file copy on the RunFinished() method

How to reference assembly from GAC?

I have installed the strong named assembly TestReflection into the GAC (I am using .NET 4.0 and VS 2010).
Different versions of the TestReflection DLL are in GAC of .NET 4.0 (C:\WINDOWS\Microsoft.NET\assembly\GAC_32\TestReflection\), however, the assembly does not appear in the "Project" -> "Add reference" box of VS 2010.
How can I refer to my assembly deployed in GAC at design time from another project?
This page says that:
You cannot add references from the Global Assembly Cache (GAC), as it is strictly part of the run-time environment.
Referring to this statement, I would like to know how to make your project's DLL shared assembly for other consumers if it's the requirement?
The dll's shown in the .Net tab of the "Add references" dialog are not actually the ones registered in the GAC. They are found by searching a few paths on your filesystem.
The paths being searched are located by Visual Studio by looking up the following registry entries:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NetFramework\{Version}\AssemblyFoldersEx\
There should be some keys added there already, so if you want your own dll to show up on the .Net tab, you can add it to one of the folders defined there. You could also add a new registry key pointing to a custom folder, which would only contain your own dll's.
The GAC is only meant for loading assemblies at runtime after your application has been deployed, so I don't think you should use it while developing. When you deploy your app, make sure to set "Copy local" to false on your reference so the dll won't be copied to the bin folder, and then install it into the GAC and it will be loaded from there instead.
Another simple option would be to manually edit the project file as XML in visual studio (You will have to unload the project first), and simply add node <Reference Include="<name of dll>" /> in MSBuild project file. After reloading the project, VS will pick up the reference without problem.
If you want to add Global Assembly Cache references to your VS2010 project, there is an extension you can use: Muse.VSExtensions.
It has some quirks but does a decent job. Check it out...
The answer is the Reference Paths in the property windows, you have to set it with the GAC path
Please see my post here:

VS.net 2010 Template and references

What is the best way to reference DLL (without copying localy into the projet) when creating a project from a "Template" project in VS.net 2010? Because, as known, project template can only make a template for a Project, not solution.
UPDATE
My question were not clear :
I want to know how to a project, lets say "Project1", that has few libraries with property "Copy Local" set to false in ASP.net and then use this project as "Template". Referencing DLL in the "project2", the one who use the "project1" as template, is not done properly without bringing each DLL into the project2 directory and recreate the same directory listning as project1. Is there a way to make a template do it all for ya?
A reference DLL won't get copied if it is registered in the GAC. Trying to avoid the copy for non-GAC-ed assemblies is possible, set the Copy Local property to False. It is however pretty unusual to do so, you can't debug the code because the CLR cannot find the required assembly at run time. Not being able to debug code is, well, a problem.

Resources