in Sharpmake.Generators/VisualStudio/Csproj.cs [1138:1701]
private void Generate(
CSharpProject project,
List<Project.Configuration> unsortedConfigurations,
string projectPath,
string projectFile,
List<string> generatedFiles,
List<string> skipFiles
)
{
var itemGroups = new ItemGroups();
// Need to sort by name and platform
List<Project.Configuration> configurations = unsortedConfigurations.OrderBy(conf => conf.Name + conf.Platform).ToList();
var projectFrameworksPerConf = configurations.ToDictionary(conf => conf, GetTargetFramework);
var projectFrameworks = projectFrameworksPerConf.Values.Distinct().ToList();
itemGroups.SetTargetFrameworks(projectFrameworks);
// valid that 2 conf name in the same project don't have the same name
var configurationNameMapping = new Dictionary<string, Project.Configuration>();
string assemblyName = null;
foreach (Project.Configuration conf in configurations)
{
if (assemblyName == null)
assemblyName = conf.AssemblyName;
else if (assemblyName != conf.AssemblyName)
throw new Error("The assemblyName can't be different between configurations of a same project. {0} != {1} in {2}", assemblyName, conf.AssemblyName, projectFile);
//set the default outputType
if (conf.Output == Project.Configuration.OutputType.Exe)
conf.Output = Project.Configuration.OutputType.DotNetConsoleApp;
if (conf.Output == Project.Configuration.OutputType.Dll)
throw new Error("OutputType for C# projects must be either DotNetClassLibrary, DotNetConsoleApp or DotNetWindowsApp");
string projectUniqueName = conf.Name + Util.GetToolchainPlatformString(conf.Platform, conf.Project, conf.Target);
configurationNameMapping[projectUniqueName] = conf;
// set generator information
conf.GeneratorSetOutputFullExtensions(".exe", ".exe", ".dll", ".pdb");
}
string outputType;
switch (configurations[0].Output)
{
case Project.Configuration.OutputType.DotNetWindowsApp:
outputType = "WinExe";
break;
case Project.Configuration.OutputType.DotNetClassLibrary:
outputType = "Library";
break;
case Project.Configuration.OutputType.DotNetConsoleApp:
default:
outputType = "Exe";
break;
}
string projectTypeGuids = RemoveLineTag;
switch (project.ProjectTypeGuids)
{
case CSharpProjectType.Test:
projectTypeGuids = ProjectTypeGuids.ToOption(ProjectTypeGuids.CSharpTestProject);
break;
case CSharpProjectType.Vsix:
projectTypeGuids = ProjectTypeGuids.ToOption(ProjectTypeGuids.VsixProject);
break;
case CSharpProjectType.Vsto:
projectTypeGuids = ProjectTypeGuids.ToOption(ProjectTypeGuids.VstoProject);
break;
case CSharpProjectType.Wpf:
projectTypeGuids = ProjectTypeGuids.ToOption(ProjectTypeGuids.WpfProject);
break;
case CSharpProjectType.Wcf:
projectTypeGuids = ProjectTypeGuids.ToOption(ProjectTypeGuids.WcfProject);
break;
case CSharpProjectType.AspNetMvc5:
projectTypeGuids = ProjectTypeGuids.ToOption(ProjectTypeGuids.AspNetMvc5Project);
break;
}
var resolver = new Resolver();
_projectPath = projectPath;
_projectPathCapitalized = Util.GetCapitalizedPath(projectPath);
_projectConfigurationList = configurations;
var memoryStream = new MemoryStream();
var writer = new StreamWriter(memoryStream);
string targetFrameworkString;
DevEnv devenv = configurations.Select(
conf => conf.Target.GetFragment<DevEnv>()).Distinct().Single();
bool isNetCoreProjectSchema = project.ProjectSchema == CSharpProjectSchema.NetCore ||
(project.ProjectSchema == CSharpProjectSchema.Default &&
(projectFrameworks.Any(x => x.DotNetFramework.IsDotNetCore() || x.DotNetFramework.IsDotNetStandard()) || projectFrameworks.Count > 1)
);
if (isNetCoreProjectSchema)
{
Write(Template.Project.ProjectBeginNetCore, writer, resolver);
targetFrameworkString = GetTargetFrameworksString(projectFrameworks.ToArray());
}
else
{
var framework = projectFrameworks.Single().DotNetFramework;
targetFrameworkString = Util.GetDotNetTargetString(framework);
using (resolver.NewScopedParameter("toolsVersion", Util.GetToolVersionString(devenv)))
{
// xml begin header
switch (devenv)
{
case DevEnv.vs2015:
Write(Template.Project.ProjectBegin, writer, resolver);
break;
case DevEnv.vs2017:
case DevEnv.vs2019:
case DevEnv.vs2022:
Write(Template.Project.ProjectBeginVs2017, writer, resolver);
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
var preImportCustomProperties = new Dictionary<string, string>(project.PreImportCustomProperties);
AddPreImportCustomProperties(preImportCustomProperties, project, projectPath);
WriteCustomProperties(preImportCustomProperties, project, writer, resolver);
var preImportProjects = new List<ImportProject>(project.PreImportProjects);
WriteImportProjects(preImportProjects.Distinct(EqualityComparer<ImportProject>.Default), project, configurations.First(), writer, resolver);
// generate all configuration options onces...
var options = new Dictionary<Project.Configuration, Options.ExplicitOptions>();
foreach (Project.Configuration conf in _projectConfigurationList)
{
_projectConfiguration = conf;
Options.ExplicitOptions option = GenerateOptions(project, conf);
_projectConfiguration = null;
options.Add(conf, option);
}
string netCoreEnableDefaultItems = RemoveLineTag;
string defaultItemExcludes = RemoveLineTag;
string targetFrameworkVersionString = "TargetFrameworkVersion";
string projectPropertyGuid = configurations[0].ProjectGuid;
string projectConfigurationCondition = Template.Project.DefaultProjectConfigurationCondition;
if (isNetCoreProjectSchema)
{
netCoreEnableDefaultItems = project.EnableDefaultItems.ToString().ToLowerInvariant();
if (project.DefaultItemExcludes.Count > 0)
{
defaultItemExcludes = string.Join(";", project.DefaultItemExcludes);
}
targetFrameworkVersionString = "TargetFramework";
projectPropertyGuid = RemoveLineTag;
if (projectFrameworks.Count() > 1)
{
projectConfigurationCondition = Template.Project.MultiFrameworkProjectConfigurationCondition;
targetFrameworkVersionString = "TargetFrameworks";
}
}
string restoreProjectStyleString = RemoveLineTag;
if (project.ExplicitNugetRestoreProjectStyle != false && project.NuGetReferenceType != Project.NuGetPackageMode.VersionDefault)
{
switch (project.NuGetReferenceType)
{
case Project.NuGetPackageMode.PackageReference:
restoreProjectStyleString = "PackageReference";
break;
case Project.NuGetPackageMode.PackageConfig:
case Project.NuGetPackageMode.ProjectJson:
throw new Error($"Unsupported explicit NuGetReferenceType \"{project.NuGetReferenceType}\"");
default:
throw new ArgumentOutOfRangeException();
}
}
GeneratedAssemblyConfigTemplate generatedAssemblyConfigTemplate = new GeneratedAssemblyConfigTemplate(project.GeneratedAssemblyConfig, isNetCoreProjectSchema, RemoveLineTag);
using (resolver.NewScopedParameter("project", project))
using (resolver.NewScopedParameter("guid", projectPropertyGuid))
using (resolver.NewScopedParameter("options", options[_projectConfigurationList[0]]))
using (resolver.NewScopedParameter("outputType", outputType))
using (resolver.NewScopedParameter("targetFramework", targetFrameworkString))
using (resolver.NewScopedParameter("targetFrameworkVersionString", targetFrameworkVersionString))
using (resolver.NewScopedParameter("projectTypeGuids", projectTypeGuids))
using (resolver.NewScopedParameter("assemblyName", assemblyName))
using (resolver.NewScopedParameter("defaultPlatform", Util.GetToolchainPlatformString(project.DefaultPlatform ?? configurations[0].Platform, project, null)))
using (resolver.NewScopedParameter("netCoreEnableDefaultItems", netCoreEnableDefaultItems))
using (resolver.NewScopedParameter("defaultItemExcludes", defaultItemExcludes))
using (resolver.NewScopedParameter("GeneratedAssemblyConfigTemplate", generatedAssemblyConfigTemplate))
using (resolver.NewScopedParameter("NugetRestoreProjectStyleString", restoreProjectStyleString))
using (resolver.NewScopedParameter("GenerateDocumentationFile", project.GenerateDocumentationFile ? "true" : RemoveLineTag))
{
Write(Template.Project.ProjectDescription, writer, resolver);
}
if (!string.IsNullOrEmpty(project.ApplicationIcon))
{
using (resolver.NewScopedParameter("iconpath", Util.PathGetRelative(_projectPathCapitalized, Project.GetCapitalizedFile(project.ApplicationIcon))))
Write(Template.ApplicationIcon, writer, resolver);
}
string appManifest = project.ApplicationManifest;
if (!string.IsNullOrEmpty(appManifest))
{
appManifest = project.NoneFiles.FirstOrDefault(s => s.EndsWith(appManifest, StringComparison.OrdinalIgnoreCase));
if (appManifest != null)
{
appManifest = Util.PathGetRelative(_projectPathCapitalized, Project.GetCapitalizedFile(appManifest));
using (resolver.NewScopedParameter("applicationmanifest", appManifest))
Write(Template.ApplicationManifest, writer, resolver);
}
}
if (!string.IsNullOrEmpty(project.StartupObject))
{
using (resolver.NewScopedParameter("startupobject", project.StartupObject))
Write(Template.StartupObject, writer, resolver);
}
if (project.NoWin32Manifest)
{
Write(Template.NoWin32Manifest, writer, resolver);
}
if (project.UseMSBuild14IfAvailable)
{
Write(Template.MSBuild14PropertyGroup, writer, resolver);
}
WriteCustomProperties(project.CustomProperties, project, writer, resolver);
if (project.ProjectTypeGuids == CSharpProjectType.Wcf)
{
string wcfAutoStart = RemoveLineTag;
if (project.WcfAutoStart.HasValue)
wcfAutoStart = project.WcfAutoStart.ToString();
using (resolver.NewScopedParameter("AutoStart", wcfAutoStart))
using (resolver.NewScopedParameter("WCFExtensionGUID", ProjectTypeGuids.WindowsCommunicationFoundation.ToString("B").ToUpper()))
Write(Template.ProjectExtensionsWcf, writer, resolver);
}
if (project.ProjectTypeGuids == CSharpProjectType.Vsto)
{
var vstoProject = project as CSharpVstoProject;
if (vstoProject == null)
throw new InvalidDataException("VSTO project was not correctly initialized. Use CSharpVstoProject instead of CSharpProject");
using (resolver.NewScopedParameter("AddInNamespace", project.RootNamespace))
using (resolver.NewScopedParameter("OfficeApplication", vstoProject.Application.ToString()))
using (resolver.NewScopedParameter("OfficeSDKVersion", vstoProject.OfficeSdkVersion))
Write(Template.ProjectExtensionsVsto, writer, resolver);
}
if (project.ProjectTypeGuids == CSharpProjectType.AspNetMvc5)
{
var aspnetProject = project as IAspNetProject;
if (aspnetProject == null)
throw new InvalidDataException("AspNet project was not correctly initialized. Implement IAspNetProject interface");
Func<bool?, string> toEnableDisable = (value) => value.HasValue ? (value.Value ? "enabled" : "disabled") : RemoveLineTag;
using (resolver.NewScopedParameter("MvcBuildViews", aspnetProject.MvcBuildViews?.ToString() ?? RemoveLineTag))
using (resolver.NewScopedParameter("UseIISExpress", aspnetProject.UseIISExpress?.ToString() ?? RemoveLineTag))
using (resolver.NewScopedParameter("IISExpressSSLPort", aspnetProject.IISExpressSSLPort?.ToString() ?? RemoveLineTag))
using (resolver.NewScopedParameter("IISExpressAnonymousAuthentication", toEnableDisable(aspnetProject.IISExpressAnonymousAuthentication)))
using (resolver.NewScopedParameter("IISExpressWindowsAuthentication", toEnableDisable(aspnetProject.IISExpressWindowsAuthentication)))
using (resolver.NewScopedParameter("IISExpressUseClassicPipelineMode", aspnetProject.IISExpressUseClassicPipelineMode?.ToString() ?? RemoveLineTag))
using (resolver.NewScopedParameter("UseGlobalApplicationHostFile", aspnetProject.UseGlobalApplicationHostFile?.ToString() ?? RemoveLineTag))
Write(Template.Project.ProjectAspNetMvcDescription, writer, resolver);
}
var additionalNones = new List<string>();
if (isNetCoreProjectSchema)
{
string launchSettingsJson = LaunchSettingsJson.Generate(_builder, project, projectPath, _projectConfigurationList, generatedFiles, skipFiles);
if (launchSettingsJson != null)
additionalNones.Add(launchSettingsJson);
}
else
{
// old style cproj.user file
string projectFilePath = Path.Combine(projectPath, projectFile) + ProjectExtension;
UserFile uf = new UserFile(projectFilePath);
uf.GenerateUserFile(_builder, project, _projectConfigurationList, generatedFiles, skipFiles);
}
// In case we need to swap out dependencies, we'll cache them here
Dictionary<string, List<DotNetDependency>> swappedNamesToDependencies = null;
// configuration general
foreach (Project.Configuration conf in _projectConfigurationList)
{
using (resolver.NewScopedParameter("platformName", Util.GetToolchainPlatformString(conf.Platform, conf.Project, conf.Target)))
using (resolver.NewScopedParameter("conf", conf))
using (resolver.NewScopedParameter("project", project))
using (resolver.NewScopedParameter("targetFramework", GetTargetFrameworksString(projectFrameworksPerConf[conf])))
using (resolver.NewScopedParameter("projectConfigurationCondition", projectConfigurationCondition))
using (resolver.NewScopedParameter("target", conf.Target))
using (resolver.NewScopedParameter("options", options[conf]))
{
Write(Template.PropertyGroupWithConditionStart, writer, resolver);
Write(Template.Project.ProjectConfigurationsGeneral, writer, resolver);
WriteProperties(conf.CustomProperties, writer, resolver);
Write(VsProjCommon.Template.PropertyGroupEnd, writer, resolver);
}
foreach (var dependencies in new[] { conf.DotNetPublicDependencies, conf.DotNetPrivateDependencies })
{
foreach (var dependency in dependencies)
{
var dependencyConfiguration = dependency.Configuration;
if (!Util.IsDotNet(dependencyConfiguration))
continue;
if (dependency.ReferenceSwappedWithOutputAssembly)
{
// cache swapped dependencies and sort them out later since we have no visibility here regarding
// multiple frameworks or optimizations from within a single Project.Configuration
// Note: even if preallocating looks tempting, the time it takes to count the entries is actually longer than the time resizing
swappedNamesToDependencies ??= new Dictionary<string, List<DotNetDependency>>(StringComparer.Ordinal);
if (!swappedNamesToDependencies.TryAdd(dependency.Configuration.AssemblyName, new List<DotNetDependency>{ dependency }))
{
swappedNamesToDependencies[dependency.Configuration.AssemblyName].Add(dependency);
}
}
else
{
string dependencyExtension = Util.GetProjectFileExtension(dependencyConfiguration);
string projectFullFileNameWithExtension = Util.GetCapitalizedPath(dependencyConfiguration.ProjectFullFileName + dependencyExtension);
string relativeToProjectFile = Util.PathGetRelative(_projectPathCapitalized, projectFullFileNameWithExtension);
// If dependency project is marked as [Compile], read the GUID from the project file
if (dependencyConfiguration.Project.SharpmakeProjectType == Project.ProjectTypeAttribute.Compile && dependencyConfiguration.ProjectGuid == null)
dependencyConfiguration.ProjectGuid = ReadGuidFromProjectFile(dependencyConfiguration);
// FIXME : MsBuild does not seem to properly detect ReferenceOutputAssembly setting.
// It may try to recompile the project if the output file of the dependency is missing.
// To counter this, the CopyLocal field is forced to false for build-only dependencies.
bool isPrivate = project.DependenciesCopyLocal.HasFlag(Project.DependenciesCopyLocalTypes.ProjectReferences) && dependency.ReferenceOutputAssembly != false;
string includeOutputGroupsInVsix = null;
if (isPrivate && project.ProjectTypeGuids == CSharpProjectType.Vsix)
{
// Includes debug symbols of private (i.e. copy local) referenced projects in the VSIX.
// This WILL override default values of <IncludeOutputGroupsInVSIX> and <IncludeOutputGroupsInVSIXLocalOnly> from Microsoft.VsSDK.targets,
// so if the VSIXs stop working, this may be the cause...
includeOutputGroupsInVsix = "DebugSymbolsProjectOutputGroup;BuiltProjectOutputGroup;BuiltProjectOutputGroupDependencies;GetCopyToOutputDirectoryItems;SatelliteDllsProjectOutputGroup";
}
itemGroups.ProjectReferences.Add(new ItemGroups.ProjectReference
{
Include = relativeToProjectFile,
Name = dependencyConfiguration.ProjectName,
Private = isPrivate,
Project = new Guid(dependencyConfiguration.ProjectGuid),
ReferenceOutputAssembly = dependency.ReferenceOutputAssembly,
IncludeOutputGroupsInVSIX = includeOutputGroupsInVsix,
});
}
}
}
foreach (var projectReferenceInfo in conf.ProjectReferencesByPath.ProjectsInfos)
{
string projectFullFileNameWithExtension = Util.GetCapitalizedPath(projectReferenceInfo.projectFilePath);
string relativeToProjectFile = Util.PathGetRelative(_projectPathCapitalized,
projectFullFileNameWithExtension);
var projectGuid = projectReferenceInfo.projectGuid;
if (projectGuid == Guid.Empty)
projectGuid = new Guid(Sln.ReadGuidFromProjectFile(projectReferenceInfo.projectFilePath));
itemGroups.ProjectReferences.Add(new ItemGroups.ProjectReference
{
Include = relativeToProjectFile,
Name = Path.GetFileNameWithoutExtension(projectReferenceInfo.projectFilePath),
Private =
project.DependenciesCopyLocal.HasFlag(
Project.DependenciesCopyLocalTypes
.ProjectReferences),
Project = projectGuid,
});
}
}
if(swappedNamesToDependencies is not null)
{
foreach (List<DotNetDependency> groupedDependencies in swappedNamesToDependencies.Values)
{
bool isMultiFramework = groupedDependencies.Select(d => d.Configuration.Target.GetFragment<DotNetFramework>()).Distinct().Count() > 1;
foreach (var dependency in groupedDependencies.OrderByDescending(d => d.Configuration.Target.GetOptimization()))
{
TargetFramework targetFramework = GetTargetFramework(dependency.Configuration);
string dllPath = Path.Combine(dependency.Configuration.TargetPath, $"{dependency.Configuration.AssemblyName}{dependency.Configuration.DllFullExtension}");
var referencesByPath = new ItemGroups.Reference
{
Include = $"{dependency.Configuration.AssemblyName}{(isMultiFramework ? "-" + GetTargetFrameworksString(targetFramework) : "")}",
SpecificVersion = false,
HintPath = Util.PathGetRelative(_projectPathCapitalized, dllPath),
Private = project.DependenciesCopyLocal.HasFlag(Project.DependenciesCopyLocalTypes.ExternalReferences),
};
itemGroups.AddReference(targetFramework, referencesByPath);
}
}
}
if (project.RunPostBuildEvent != Options.CSharp.RunPostBuildEvent.OnBuildSuccess)
{
using (resolver.NewScopedParameter("RunPostBuildEvent", Enum.GetName(typeof(Options.CSharp.RunPostBuildEvent), project.RunPostBuildEvent)))
Write(Template.Project.ProjectConfigurationsRunPostBuildEvent, writer, resolver);
}
string netCoreSdk = null;
if (isNetCoreProjectSchema)
{
netCoreSdk = "Microsoft.NET.Sdk";
if (project.NetCoreSdkType != NetCoreSdkTypes.Default)
netCoreSdk += "." + project.NetCoreSdkType.ToString();
using (resolver.NewScopedParameter("importProject", "Sdk.props"))
using (resolver.NewScopedParameter("sdkVersion", netCoreSdk))
Write(Template.Project.ImportProjectSdkItem, writer, resolver);
}
GenerateFiles(project, configurations, itemGroups, additionalNones, generatedFiles, skipFiles);
#region <Choose> section
Dictionary<string, List<IResolvable>> choiceDict =
configurations.SelectMany(c => c.ConditionalReferencesByPath.Select(p => new Tuple<string, string>(c.ConditionalReferencesByPathCondition, p)))
.GroupBy(t => t.Item1).ToDictionary(g => g.Key, g => g.Select(p => new ItemGroups.Reference
{
Include = Path.GetFileNameWithoutExtension(p.Item2),
SpecificVersion = false,
HintPath = Util.PathGetRelative(_projectPathCapitalized, p.Item2),
Private = project.DependenciesCopyLocal.HasFlag(Project.DependenciesCopyLocalTypes.ExternalReferences) ? default(bool?) : false
} as IResolvable).ToList());
if (choiceDict.Count != 0)
{
Choose choose = new Choose
{
Choices = choiceDict
};
writer.Write(choose.Resolve(resolver));
}
#endregion
#region WCF support
// We need to know if there is any WCFMetadataStorage detected before generating <WCFMetadata>
if (itemGroups.WCFMetadataStorages.Count > 0)
{
writer.Write(Template.ItemGroups.ItemGroupBegin);
using (resolver.NewScopedParameter("baseStorage", project.WcfBaseStorage))
Write(Template.ItemGroups.WCFMetadata, writer, resolver);
writer.Write(Template.ItemGroups.ItemGroupEnd);
}
#endregion
using (resolver.NewScopedParameter("project", project))
writer.Write(itemGroups.Resolve(resolver));
var importProjects = new List<ImportProject>(project.ImportProjects);
// For .NET Core the default import project is inferred instead of explicit.
if (isNetCoreProjectSchema)
{
importProjects.RemoveAll(i => i.Project == CSharpProject.DefaultImportProject);
}
if (project.ProjectTypeGuids == CSharpProjectType.Vsix)
{
// Add an extra tag to setup VSIX on VS2017, which is generated on Visual Studio
// 2017. (This is likely a Microsoft hack to plug 2017 on the 2015 toolset.)
if (devenv.IsVisualStudio() && devenv >= DevEnv.vs2017)
writer.Write(CSproj.Template.Project.VsixConfiguration);
}
project.AddCSharpSpecificImportProjects(importProjects, devenv);
// Add custom .targets files as import projects.
foreach (string targetsFile in project.CustomTargetsFiles)
{
importProjects.AddRange(targetsFile.Select(f => new ImportProject() { Project = targetsFile }));
}
WriteImportProjects(importProjects.Distinct(EqualityComparer<ImportProject>.Default), project, configurations.First(), writer, resolver);
foreach (var element in project.UsingTasks)
{
using (resolver.NewScopedParameter("project", project))
using (resolver.NewScopedParameter("usingTaskElement", element))
{
Write(Template.UsingTaskElement.UsingTask, writer, resolver);
}
}
foreach (var element in project.CustomTargets)
{
using (resolver.NewScopedParameter("project", project))
using (resolver.NewScopedParameter("targetElement", element))
{
if (string.IsNullOrEmpty(element.TargetParameters))
Write(Template.TargetElement.CustomTargetNoParameters, writer, resolver);
else
Write(Template.TargetElement.CustomTarget, writer, resolver);
}
}
if (project.ProjectTypeGuids == CSharpProjectType.AspNetMvc5)
{
var aspnetProject = project as IAspNetProject;
if (aspnetProject == null)
throw new InvalidDataException("AspNet project was not correctly initialized. Use AspNetProject instead of CSharpProject");
using (resolver.NewScopedParameter("UseIIS", aspnetProject.UseIIS?.ToString() ?? RemoveLineTag))
using (resolver.NewScopedParameter("AutoAssignPort", aspnetProject.AutoAssignPort?.ToString() ?? RemoveLineTag))
using (resolver.NewScopedParameter("DevelopmentServerPort", aspnetProject.DevelopmentServerPort?.ToString() ?? RemoveLineTag))
using (resolver.NewScopedParameter("DevelopmentServerVPath", aspnetProject.DevelopmentServerVPath ?? RemoveLineTag))
using (resolver.NewScopedParameter("IISUrl", aspnetProject.IISUrl ?? RemoveLineTag))
using (resolver.NewScopedParameter("NTLMAuthentication", aspnetProject.NTLMAuthentication?.ToString() ?? RemoveLineTag))
using (resolver.NewScopedParameter("UseCustomServer", aspnetProject.UseCustomServer?.ToString() ?? RemoveLineTag))
using (resolver.NewScopedParameter("SaveServerSettingsInUserFile", aspnetProject.SaveServerSettingsInUserFile?.ToString() ?? RemoveLineTag))
using (resolver.NewScopedParameter("AspNetMvc5ExtensionGUID", ProjectTypeGuids.AspNetMvc5.ToString("B").ToUpper()))
Write(Template.ProjectExtensionsAspNetMvc5, writer, resolver);
}
WriteEvents(options, writer, resolver);
if (isNetCoreProjectSchema)
{
using (resolver.NewScopedParameter("importProject", "Sdk.targets"))
using (resolver.NewScopedParameter("sdkVersion", netCoreSdk))
Write(Template.Project.ImportProjectSdkItem, writer, resolver);
}
Write(Template.Project.ProjectEnd, writer, resolver);
// Write the project file
writer.Flush();
var cleanMemoryStream = Util.RemoveLineTags(memoryStream, RemoveLineTag);
var projectFileInfo = new FileInfo(Path.Combine(projectPath, projectFile + ProjectExtension));
if (_builder.Context.WriteGeneratedFile(project.GetType(), projectFileInfo, cleanMemoryStream))
generatedFiles.Add(projectFileInfo.FullName);
else
skipFiles.Add(projectFileInfo.FullName);
writer.Close();
}