Visual studio project template creating solution file in outer directory - visual-studio

I am creating multiproject template for Visual studio using VSTemplate.
I am new to project template and refering this url to create multi project template for Visual Studio.
<VSTemplate Version="2.0.0" Type="ProjectGroup"
xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">
<TemplateData>
<Name>MVC with Repo and UoW</Name>
<Description>Basic by Jenish</Description>
<Icon>Icon.ico</Icon>
<ProjectType>CSharp</ProjectType>
<ProjectSubType>
</ProjectSubType>
<SortOrder>1000</SortOrder>
<CreateNewFolder>false</CreateNewFolder>
<DefaultName>MVC</DefaultName>
<ProvideDefaultName>true</ProvideDefaultName>
<LocationField>Enabled</LocationField>
<EnableLocationBrowseButton>true</EnableLocationBrowseButton>
</TemplateData>
<TemplateContent>
<ProjectCollection>
<ProjectTemplateLink ProjectName="$safeprojectname$.Common">
KLS.Common\MyTemplate.vstemplate
</ProjectTemplateLink>
<ProjectTemplateLink ProjectName="$safeprojectname$.Data.Contract">
KLS.Data.Contract\MyTemplate.vstemplate
</ProjectTemplateLink>
<ProjectTemplateLink ProjectName="$safeprojectname$.Data.Repositories">
KLS.Data.Repositories\MyTemplate.vstemplate
</ProjectTemplateLink>
<ProjectTemplateLink ProjectName="$safeprojectname$.Manager">
KLS.Manager\MyTemplate.vstemplate
</ProjectTemplateLink>
<ProjectTemplateLink ProjectName="$safeprojectname$.Models">
KLS.Models\MyTemplate.vstemplate
</ProjectTemplateLink>
<ProjectTemplateLink ProjectName="$safeprojectname$.Web">
KLSFoods\MyTemplate.vstemplate
</ProjectTemplateLink>
</ProjectCollection>
</TemplateContent>
<WizardExtension>
<Assembly>RestTemplateWizard, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c9a76f51a8a9555f</Assembly>
<FullClassName>RestTemplateWizard.RootWizard</FullClassName>
</WizardExtension>
</VSTemplate>
screenshot 1:
As per above screen shot Mytemplate.vstemplate is main root file and all the folder except packages contains separate vstemplate file for each project.
Now problem is I want same structure to be generated as it appears on the first screen shot but it generates solution in outer directory. Is there any way I can force the template to create solution as per screen shot1.
Template is currently generating the solution like this.
screenshot 2:
Mvc1 will hold all the project folder and what I want is create solution file where all the project folder is defined. because currently it refers the packages folder wrongly
Thanks in advance.

3 years late, but this may help others.
1) In your wizard class declare a DTE field, and save the automationObject parameter to RunStarted(...) in this field:
public class MyWizard : IWizard
{
DTE dte;
...
public void RunStarted( object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams )
{
dte = automationObject as DTE;
...
2) In RunFinished, use the dte object to save the solution wherever you want:
public void RunFinished()
{
if( dte != null )
{
var solution = dte.Solution;
var path = <whatever path you want>;
solution.SaveAs( path );
}
...
You may want to inspect the contents of replacementsDictionary at RunStarted and use one of the values in there; for instance, you can use the $destinationdirectory$ entry to construct the path to the solution file (I'm using that one).

I had the same issue, my workaround was to edit the solution file (*.sln) and move the file in the expected folder.
This is the folder structure generated by the template (not what I was expecting):
My Solution folder:
notice the .sln file not in the same folder of the projects
folder DDD_Backend10xxxx, contains all the projects:
step 1: Move the .sln file in the sub folder containing all the projects (as required for project to work):
*.sln file moved to same folder with the rest of the projects
The .sln file is now with the project folders and in the correct solution folder level.
step 2: open and edit the .sln file and modify the paths of ALL the projects:
Paths not edited that cause ERRORS:
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BusinessLayer", "DDD_Backend10xxxx\BusinessLayer", "{F9E1B70C-F692-414B-97C6-BCEC22F6C1F3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BusinessLayer", "DDD_Backend10xxxx\BusinessLayer\BusinessLayer.csproj", "{0CF94CF4-97C6-4079-8F60-672CBE9B77D5}"
EndProject
//Other project references...
Fixed edited paths: remove the folder "DDD_Backend10xxxx" from path
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BusinessLayer", "BusinessLayer", "{F9E1B70C-F692-414B-97C6-BCEC22F6C1F3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BusinessLayer", "BusinessLayer\BusinessLayer.csproj", "{0CF94CF4-97C6-4079-8F60-672CBE9B77D5}"
EndProject
//Other project references...
step 3: modify the primary/root project root_project_name.csproj file, for nuget extension reference path.
Modify any reference to the packages folder, so that they'll reference the packages folder in the same folder level.
ie.
from: Import Project="....\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1
to:
Import Project="..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1
This is an essential reference for nuget package update or installation.
step 4: Run nuget to update/restore the packages.
Once nuget updates/restores the packages a "packages" folder will be created in the correct folder level.
(Run the command update-package -reinstall in the Package Manager Console window.)

Instead of moving the .sln file and then editing it, just do a "Save as..." for the solution and put it in the same directory as the projects. Then you can then delete the original .sln file. Visual Studio will adjust all of the paths in the new .sln file to match where you are placing it.

That looks correct to me. And if you look at the documentation in the URL you provided it sounds like this is working correctly.
The solution should sit in the same directory as the project folders. If you look at screenshot1, that seems to be what is happening. It looks like in your example you're only creating a single project called MVC1 which is the only project in a solution called MVC1. The code snippet you've provided also doesn't match up with screenshot2. You may also want to include the template file you're actually using to generate the solution as well.

Related

Visual Studio .vstemplate files not copying files using $projectname$ parameter

I am having trouble getting Visual Studio project templates to work correctly.
I have edited the .vstemplate file in order to allow VS to rename project files when a new project is created from the template.
Some of the files are not copied or renamed when the new project is created.
I have a C++ project named Minimal that I have exported as a template.
I am currently NOT using any replaceable parameters in the Minimal template project.
The Minimal.zip folder in the Project Templates directory contains:
__TemplateIcon.ico (created by VS when the project was exported)
Minimal.cpp (my code)
Minmal.rc (a resource file containing a string table with one entry)
Minimal.vcxproj (created by VS at project creation time),
Minimal.vcxproj.filters (created by VS at project creation time)
MyTemplate.vstemplate (an XML file created by VS when the project was exported)
resource.h (created by VS at project creation time).
The MyTemplate.vstemplate file looks like this after editing:
<VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Project">
<TemplateData>
<Name>Minimal</Name>
<Description><No description available></Description>
<ProjectType>VC</ProjectType>
<ProjectSubType>
</ProjectSubType>
<SortOrder>1000</SortOrder>
<CreateNewFolder>true</CreateNewFolder>
<DefaultName>Minimal</DefaultName>
<ProvideDefaultName>true</ProvideDefaultName>
<LocationField>Enabled</LocationField>
<EnableLocationBrowseButton>true</EnableLocationBrowseButton>
<Icon>__TemplateIcon.ico</Icon>
</TemplateData>
<TemplateContent>
<Project TargetFileName="Minimal.vcxproj" File="Minimal.vcxproj" ReplaceParameters="true">
<ProjectItem ReplaceParameters="false" TargetFileName="$projectname$.vcxproj.filters">Minimal.vcxproj.filters</ProjectItem>
<ProjectItem ReplaceParameters="false" TargetFileName="$projectname$.cpp">Minimal.cpp</ProjectItem>
<ProjectItem ReplaceParameters="false" TargetFileName="resource.h">resource.h</ProjectItem>
<ProjectItem ReplaceParameters="true" TargetFileName="$projectname$.rc">Minimal.rc</ProjectItem>
</Project>
</TemplateContent>
</VSTemplate>
I edited the ProjectItem entries to use the $projectname$ parameters.
Two ProjectItems have ReplaceParameters set to "false" and a TargetFileName set to $projectname$.
One ProjectItem has ReplaceParameters set to "false" and TargetFileName unedited.
One ProjectItem has ReplaceParameters set to "true" and TargetFileName set to $projectname$.
I have a project named Test that I created from the Minimal template.
I would expect the Test project folder to contain one file for each ProjectItem, and the files that use the $projectname$ parameter to be renamed as Test.something.
The Test project folder actually contains this:
Test.sln (created by VS)
resource.h (not renamed, as expected)
Test.vcxproj (renamed, as expected)
Test.vcxproj.filters (renamed, as expected)
Test.vcxoproj.user (created by VS).
The Test project folder does not contain any .cpp or .rc file.
I have also tried not using $projectname$ for the .cpp file and the .rc file, and just used their original names, and they get copied into the new project.
Does anyone know what I need to do to make it work correctly with renamed files?

The following projects do not have a valid ProjectGuid and were not built using a valid solution (.sln) thus will be skipped from analysis

When you are building a dotnet core project with SonarQube you may be facing the error in the log:
WARNING: The following projects do not have a valid ProjectGuid and were not built using a valid solution (.sln) thus will be skipped from analysis...
What should you do?
As dotnet core projects (.csproj) will not have <ProjectGuid>...</ProjectGuid> tag specified in the default template this needs to be manually added.
So you need to edit the .csproj file like this:
<PropertyGroup>
<!-- other properties here -->
<!-- SonarQube needs this -->
<ProjectGuid>{E2CEBBAF-6DF7-41E9-815D-9AD4CF90C844}</ProjectGuid>
Make sure to place your own GUID inside the <ProjectGuid>...</ProjectGuid> Tag
Here's a solution to adding the missing xml elements in powershell.
$paths = Get-ChildItem -include *.csproj -Recurse
foreach($pathobject in $paths)
{
$path = $pathobject.fullname
$doc = New-Object System.Xml.XmlDocument
$doc.Load($path)
$child = $doc.CreateElement("ProjectGuid")
$child.InnerText = "{"+[guid]::NewGuid().ToString().ToUpper()+"}"
$node = $doc.SelectSingleNode("//Project/PropertyGroup")
$node.AppendChild($child)
$doc.Save($path)
}
The solution I came up with is to build the solution, not the project files. If using Azure DevOps, use **/*.sln instead of **/*.csproj in your DotNetCoreCLI build step.
Note that the ProjectGuid can be found in the .sln file if you use such a file.
The .sln file has a long line similar to:
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Project1",
"path\Project1.csproj", "{307CB8DB-DC9C-4830-AA92-D842D89E17E0}"
In it, the first Guid (inside Project(...)) specifies the type of the project, and you can find a "dictionary" on the web that translates each Guid there to a human-readable type. For example, {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} means "C#" project type.
But the last Guid (given after the filename) in the .sln entry is the ProjectGuid.
So if you use an .sln file always, also from the SonarQube runs, there should be no need to insert a Guid in the .csproj file.
The other place the ProjectGuid can be specified is in the .csproj. Like other answers say, it looks like this:
<PropertyGroup>
<!-- possibly other properties -->
<ProjectGuid>{307CB8DB-DC9C-4830-AA92-D842D89E17E0}</ProjectGuid>
</PropertyGroup>
So if you never use .sln file in any context, you can just create any new Guid. In Visual Studio, you can use "Tools" - "Create GUID" - "Registry Format" to create a fresh Guid and and have it formatted correctly for this purpose.
However, from the above, it is clear that if you do use an .sln file in some contexts (like from Visual Studio during development/maintenance), but do not use that .sln file from the SonarQube run, then the ProjectGuid you put in the .csproj should match the one present in the .sln. One way you could achieve it, when creating new projects, is to first add the new project to the .sln, then do a diff ("Compare with Unmodified" or similar) on your .sln file using your version control software (like Git) to obtain the ProjectGuid, and copy/paste that Guid, including braces {...} into the new .csproj file.

Multi-project Visual Studio template with solution folders containing files

I'm creating a multi-project template in Visual Studio, and I got the basics up and running quite nicely.
MySolution.vstemplate:
<VSTemplate Version="2.0.0" Type="ProjectGroup" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">
<TemplateData>
<Name>My standard .NET solution</Name>
<Description>My standard .NET solution</Description>
<Icon>myicon.ico</Icon>
<ProjectType>CSharp</ProjectType>
<DefaultName>Customer.Project</DefaultName>
<SortOrder>5000</SortOrder>
</TemplateData>
<TemplateContent>
<ProjectCollection>
<SolutionFolder Name=".nuget">
.... here I'd like to link to a few on-disk files to be included ......
</SolutionFolder>
<SolutionFolder Name="Batchjobs">
<ProjectTemplateLink ProjectName="$safeprojectname$.Batchjob">My batchjob\MyBatchjob.vstemplate</ProjectTemplateLink>
</SolutionFolder>
<SolutionFolder Name="build">
.... here I'd like to link to a few on-disk files to be included ......
</SolutionFolder>
<SolutionFolder Name="Testing">
<ProjectTemplateLink ProjectName="$safeprojectname$.IntegrationTests">MyIntegrationTests\MyIntegrationTests.vstemplate</ProjectTemplateLink>
<ProjectTemplateLink ProjectName="$safeprojectname$.UnitTests">MyUnitTests\MyUnitTests.vstemplate</ProjectTemplateLink>
</SolutionFolder>
</ProjectCollection>
</TemplateContent>
</VSTemplate>
However: the solution I'm trying to create with the several contained projects in reality also has several solution folders that correspond to on-disk directories and they contain some files; one is for the NuGet stuff, another is config and PowerShell script for our build process, and more.
I haven't been able to find anything online that would show me how to include solution folder and file items in them into my templated output solution. I can easily create solution folders - but it seems I cannot add any files to them in the templating process.....
Or am I missing something really simple here? Any ideas?
The VSProjectTemplate don't be able to do this. You just can add SolutionFolders with Projects and Files inside the projects. In my case, i did resolved creating another project in my solution to group that files of solution Folders and then modified my solution to refer the files on the new projects and not from the solution folder, and then exporting the complete solution.
Solution Folder 1
Project 1.csproj
File 1.cs
Project 2.csproj
File 2.cs
Solution Folder 2
File 3.cs
Project 3.csproj
File 4.cs
Project 4.csproj
File 5.cs
I have created a new project named "Project 5" inside the "Solution Folder 2" and then did access files on them.
Solution Folder 2
Project 3.csproj
File 4.cs
Project 4.csproj
File 5.cs
Project 5.csproj
File 3.cs
This did the template create the all solution folders, projects and files of the solution.

How to change containing folder name for a project in VS 2010 template

I have created a multi-project template in VS 2010 and the folder structure created is:
Service1
MyService.Service1.CommunicationLayer
-->MyService.Service1.CommunicationLayer.csproj
MyService.Service1.DataAccessLayer
-->MyService.Service1.DataAccessLayer.csproj
MyService.Service1.ServiceLayer
-->MyService.Service1.ServiceLayer.csproj
But I need the structure as follows:
Service1
Communication
-->MyService.Service1.CommunicationLayer.csproj
DataAccess
-->MyService.Service1.DataAccessLayer.csproj
Services
-->MyService.Service1.ServiceLayer.csproj
Also, I need my SolutionFolder name to be set to Service1 which will be the name of project user provides.
Here is the .vstemplate file I am using:
`<!--Outer .vstemplate file -->
<VSTemplate Version="2.0.0" Type="ProjectGroup"
xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">
<TemplateData>
<Name>DataAccessService</Name>
<Description>Data Access Service Template</Description>
<ProjectType>CSharp</ProjectType>
<Icon>__TemplateIcon.ico</Icon>
<CreateNewFolder>true</CreateNewFolder>
<ProvideDefaultName >true</ProvideDefaultName>
<DefaultName>DALService</DefaultName>
</TemplateData>
<TemplateContent>
<ProjectCollection>
<ProjectTemplateLink ProjectName="MyService.$safeprojectname$.CommunicationLayer">Communication\Communication.vstemplate</ProjectTemplateLink>
<ProjectTemplateLink ProjectName="MyService.$safeprojectname$.DataAccessLayer">DataAccess\DataAccess.vstemplate</ProjectTemplateLink>
<ProjectTemplateLink ProjectName="MyService.$safeprojectname$.ServiceLayer">Services\Services.vstemplate</ProjectTemplateLink>
</ProjectCollection>
</TemplateContent>
</VSTemplate>`
Any help would be appreciated.
Ok. So here is the solution I found:
I used TemplateWizard to customize my folder structure.
Create the projects with default project name and containing folder.
Create SolutionFolder using TemplateWizard.
Remove projects from Solution.
Rename the containing folder.
Add the project to SolutionFolder which I created in Step 2.
Hope this helps someone with similar issue.

VS2010: VSIX installation doesn't deploy item templates inside it

Given demo solution with two VSX-projects:
1. Add New Project -> Extensibility -> Item Template - "ItemTemplate1"
2. Add New Project -> Extensibility -> VSIX Project - "VSIXProject1"
I did no changes in "ItemTemplate1", so it constains default item template (ItemTemplate1.vstemplate):
<VSTemplate Version="3.0.0" Type="Item" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">
<TemplateData>
<Name>ItemTemplate1</Name>
<Description><No description available></Description>
<Icon>ItemTemplate1.ico</Icon>
<TemplateID>e298765c-97b8-4f4c-9b7b-a6b368f914df</TemplateID>
<ProjectType>CSharp</ProjectType>
<RequiredFrameworkVersion>2.0</RequiredFrameworkVersion>
<NumberOfParentCategoriesToRollUp>1</NumberOfParentCategoriesToRollUp>
<DefaultName>Class.cs</DefaultName>
</TemplateData>
<TemplateContent>
<References>
<Reference>
<Assembly>System</Assembly>
</Reference>
</References>
<ProjectItem ReplaceParameters="true">Class.cs</ProjectItem>
</TemplateContent>
</VSTemplate>
In VSIXProject1 I only edited source.extension.vsixmanifest adding reference to ItemTemplates1 project. After this vsixmanifest contains only one content description:
<Content>
<ItemTemplate>ItemTemplates</ItemTemplate>
</Content>
Then built it. In bin/debug I got VSIXProject1.vsix inside which I can see my item template in ItemTemplates\CSharp\1033\ItemTemplate1.zip file.
Everything looks great!
Except the fact it doesn't work. I run VSIXProject1.vsix, vsix installed (I can see it in the extension manager) but no any templates was copied to
"C:\Users\{UserName}\Documents\Visual Studio 2010\Templates\ItemTemplates" !
Templates that are installed through a VSIX don't get installed to the Templates folder in the user Documents folder. They get installed under %LocalAppData%\Microsoft\VisualStudio\10.0\Extensions\<YourExtensionFolder> with all the other content for that extension. (A VSIX install is basically just unzipping the VSIX to a folder.)
You should still be able to see the template when you try to add a new item to a C# project.
please check the website below.It has help to solve my issue.
http://silverlightdude.wordpress.com/2010/06/07/installing-the-prism-template-pack-for-visual-studio-2010/#comment-4

Resources