in src/Microsoft.VisualStudio.SlnGen/SlnFile.cs [135:227]
public static (string solutionFileFullPath, int customProjectTypeGuidCount, int solutionItemCount, Guid solutionGuid) GenerateSolutionFile(ProgramArguments arguments, IEnumerable<Project> projects, ISlnGenLogger logger)
{
List<Project> projectList = projects.ToList();
Project firstProject = projectList.First();
IReadOnlyDictionary<string, Guid> customProjectTypeGuids = SlnProject.GetCustomProjectTypeGuids(firstProject);
IReadOnlyCollection<string> solutionItems = SlnProject.GetSolutionItems(firstProject, logger).ToList();
string solutionFileFullPath = arguments.SolutionFileFullPath?.LastOrDefault();
if (solutionFileFullPath.IsNullOrWhiteSpace())
{
string solutionDirectoryFullPath = arguments.SolutionDirectoryFullPath?.LastOrDefault();
if (solutionDirectoryFullPath.IsNullOrWhiteSpace())
{
solutionDirectoryFullPath = firstProject.DirectoryPath;
}
string solutionFileName = Path.ChangeExtension(Path.GetFileName(firstProject.FullPath), "sln");
solutionFileFullPath = Path.Combine(solutionDirectoryFullPath!, solutionFileName);
}
logger.LogMessageHigh($"Generating Visual Studio solution \"{solutionFileFullPath}\" ...");
if (customProjectTypeGuids.Count > 0)
{
logger.LogMessageLow("Custom Project Type GUIDs:");
foreach (KeyValuePair<string, Guid> item in customProjectTypeGuids)
{
logger.LogMessageLow(" {0} = {1}", item.Key, item.Value);
}
}
SlnFile solution = new SlnFile
{
Platforms = arguments.GetPlatforms(),
Configurations = arguments.GetConfigurations(),
};
if (arguments.VisualStudioVersion.HasValue)
{
if (arguments.VisualStudioVersion.Version != null && Version.TryParse(arguments.VisualStudioVersion.Version, out Version version))
{
solution.VisualStudioVersion = version;
}
if (solution.VisualStudioVersion == null)
{
string devEnvFullPath = arguments.GetDevEnvFullPath(Program.CurrentDevelopmentEnvironment.VisualStudio);
if (!devEnvFullPath.IsNullOrWhiteSpace() && File.Exists(devEnvFullPath))
{
FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(devEnvFullPath);
solution.VisualStudioVersion = new Version(fileVersionInfo.ProductMajorPart, fileVersionInfo.ProductMinorPart, fileVersionInfo.ProductBuildPart, fileVersionInfo.FilePrivatePart);
}
}
}
if (SlnFile.TryParseExistingSolution(solutionFileFullPath, out Guid solutionGuid, out IReadOnlyDictionary<string, Guid> projectGuidsByPath))
{
logger.LogMessageNormal("Updating existing solution file and reusing Visual Studio cache");
solution.SolutionGuid = solutionGuid;
solution.ExistingProjectGuids = projectGuidsByPath;
arguments.LoadProjectsInVisualStudio = new[] { bool.TrueString };
}
solution.AddProjects(projectList, customProjectTypeGuids, arguments.IgnoreMainProject ? null : firstProject.FullPath);
solution.AddSolutionItems(solutionItems);
if (!arguments.EnableFolders())
{
foreach (SlnProject project in solution._projects.Distinct(new EqualityComparer<SlnProject>((x, y) => string.Equals(x.SolutionFolder, y.SolutionFolder)))
.Where(i => !string.IsNullOrWhiteSpace(i.SolutionFolder) && i.SolutionFolder.Contains(Path.DirectorySeparatorChar)))
{
logger.LogError($"The value of SlnGenSolutionFolder \"{project.SolutionFolder}\" cannot contain directory separators.");
}
}
if (!logger.HasLoggedErrors)
{
solution.Save(solutionFileFullPath, arguments.EnableFolders(), arguments.EnableCollapseFolders());
}
return (solutionFileFullPath, customProjectTypeGuids.Count, solutionItems.Count, solution.SolutionGuid);
}