private static string GetFullPathExpression(string pathToRelativize, string basePath) { return(string.Format( CultureInfo.InvariantCulture, @"$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)\{0}'))", PathUtilities.Relativize(pathToRelativize, basePath))); }
private string ProcessFolderEntry( PathTable pathTable, RelativePath folder, Dictionary <RelativePath, string> folderProjects, MultiValueDictionary <string, GuidWithName> childrenByParentGuid, StreamWriter writer) { if (folder.IsEmpty) { return(null); } string folderGuid; if (folderProjects.TryGetValue(folder, out folderGuid)) { return(folderGuid); } string name = folder.GetName().ToString(pathTable.StringTable); string currentGuid = GetGuidFromString(folder.ToString(pathTable.StringTable)); RelativePath parentFolder = folder.GetParent(); string parentGuid = ProcessFolderEntry(pathTable, parentFolder, folderProjects, childrenByParentGuid, writer); if (parentGuid != null) { AddNestedGuids(new GuidWithName(currentGuid, name), parentGuid, folder, folderProjects, childrenByParentGuid); } // Write folder. writer.Write("Project(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \""); writer.Write(name); writer.Write("\", \""); writer.Write(name); writer.Write("\", \""); writer.Write(currentGuid); writer.WriteLine("\""); // Adding package and package.config files in order to show them in the SolutionExplorer var relativePath = folder.ToString(pathTable.StringTable); var fullPath = Path.Combine(m_context.EnlistmentRootStr, relativePath); var packagePath = Path.Combine(fullPath, "package" + Names.DotDscExtension); var packageConfigPath = Path.Combine(fullPath, Names.PackageConfigDsc); var builder = new StringBuilder(); if (File.Exists(packagePath)) { var temp = PathUtilities.Relativize(packagePath, m_context.SolutionFilePathStr); builder.AppendLine("\t\t" + temp + " = " + temp); } if (File.Exists(packageConfigPath)) { var temp = PathUtilities.Relativize(packageConfigPath, m_context.SolutionFilePathStr); builder.AppendLine("\t\t" + temp + " = " + temp); } if (builder.Length > 0) { writer.WriteLine("\tProjectSection(SolutionItems) = preProject"); writer.Write(builder.ToString()); writer.WriteLine("\tEndProjectSection"); } writer.WriteLine("EndProject"); folderProjects.Add(folder, currentGuid); return(currentGuid); }
private void WriteSolution(PathTable pathTable, string solutionFilePath) { string solutionDir = Path.GetDirectoryName(solutionFilePath); // We are not intentionally deleting the vsSettingsDir! if (!Directory.Exists(solutionDir)) { Directory.CreateDirectory(solutionDir); } Tuple <string, string>[] defaultQualifierValues = new[] { Tuple.Create("Debug|Any CPU", "Debug|Any CPU"), Tuple.Create("Release|Any CPU", "Release|Any CPU") }; Tuple <string, string>[] nativeQualifierValues = new[] { Tuple.Create("Debug|Any CPU", "Debug|Win32"), Tuple.Create("Release|Any CPU", "Release|Win32") }; // TODO: Compare if the file is actually different and only write when different // TODO: Handle errors more gracefully in case someone has a 'lock' on the files. using (var stream = UpdateFile(solutionFilePath)) { using (var writer = new StreamWriter(stream)) { writer.WriteLine("Microsoft Visual Studio Solution File, Format Version 12.00"); writer.WriteLine("# Visual Studio 14"); writer.WriteLine("# Generated by IdeGeneratorAnalyzer"); writer.WriteLine("VisualStudioVersion = 14.0.24720.0"); writer.WriteLine("MinimumVisualStudioVersion = 10.0.40219.1"); var childrenByParentGuid = new MultiValueDictionary <string, GuidWithName>(); var folderProjects = new Dictionary <RelativePath, string>(); // Emit projects foreach (var msbuildFile in m_msbuildFiles) { string projectGuid = msbuildFile.Guid; string projectName = Path.GetFileNameWithoutExtension(msbuildFile.Path.ToString(m_context.PathTable)); writer.Write("Project(\""); if (msbuildFile is CsprojFile) { writer.Write(CSharpProjectTypeGuid); } else { writer.Write(NativeProjectTypeGuid); } writer.Write("\") = \""); writer.Write(projectName); writer.Write("\", \""); writer.Write(PathUtilities.Relativize(msbuildFile.Path.ToString(pathTable), solutionFilePath)); writer.Write("\", \""); writer.Write(projectGuid); writer.WriteLine("\""); writer.WriteLine("EndProject"); if (projectName.EndsWith(".g", StringComparison.OrdinalIgnoreCase)) { projectName = Path.GetFileNameWithoutExtension(projectName); } RelativePath folder = msbuildFile.RelativePath.GetParent(); if (!folder.IsEmpty && string.Equals(projectName, folder.GetName().ToString(pathTable.StringTable), StringComparison.Ordinal)) { // If the folder name matches the project name, skip the parent folder. folder = folder.GetParent(); } string folderGuid = ProcessFolderEntry(pathTable, folder, folderProjects, childrenByParentGuid, writer); if (folderGuid != null) { AddNestedGuids(new GuidWithName(projectGuid, projectName), folderGuid, folder, folderProjects, childrenByParentGuid); } } // Do not show the config file in the Solution explorer any more. We will reverse this change in future. // Write the root config.dsc and .editorconfig under the Solution items var relativeConfigPath = PathUtilities.Relativize(m_context.ConfigFilePathStr, m_context.SolutionFilePathStr); var editorConfigPath = Path.Combine(Path.GetDirectoryName(m_context.ConfigFilePathStr), ".editorconfig"); writer.WriteLine("Project(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Solution Items\", \"Solution Items\", \"" + SolutionItemsGuid + "\""); writer.WriteLine("\tProjectSection(SolutionItems) = preProject"); writer.WriteLine("\t\t" + relativeConfigPath + " = " + relativeConfigPath); if (File.Exists(editorConfigPath)) { var relativeEditorConfigPath = PathUtilities.Relativize(editorConfigPath, m_context.SolutionFilePathStr); writer.WriteLine("\t\t" + relativeEditorConfigPath + " = " + relativeEditorConfigPath); } writer.WriteLine("\tEndProjectSection"); writer.WriteLine("EndProject"); // Write parent and child relations writer.WriteLine("Global"); writer.WriteLine("\tGlobalSection(SolutionConfigurationPlatforms) = preSolution"); foreach (var qualifierValue in defaultQualifierValues) { writer.WriteLine("\t\t{0} = {1}", qualifierValue.Item1, qualifierValue.Item2); } writer.WriteLine("\tEndGlobalSection"); writer.WriteLine("\tGlobalSection(ProjectConfigurationPlatforms) = postSolution"); foreach (var msbuildFile in m_msbuildFiles) { Tuple <string, string>[] qualifierValues = defaultQualifierValues; if (msbuildFile is VcxprojFile) { qualifierValues = nativeQualifierValues; } foreach (var qualifierValue in qualifierValues) { writer.WriteLine("\t\t{0}.{1}.ActiveCfg = {2}", msbuildFile.Guid, qualifierValue.Item1, qualifierValue.Item2); writer.WriteLine("\t\t{0}.{1}.Build.0 = {2}", msbuildFile.Guid, qualifierValue.Item1, qualifierValue.Item2); } } writer.WriteLine("\tEndGlobalSection"); writer.WriteLine("\tGlobalSection(SolutionProperties) = preSolution"); writer.WriteLine("\t\tHideSolutionNode = FALSE"); writer.WriteLine("\tEndGlobalSection"); writer.WriteLine("\tGlobalSection(NestedProjects) = preSolution"); foreach (var parentGuid in childrenByParentGuid.Keys) { foreach (var children in childrenByParentGuid[parentGuid]) { writer.WriteLine("\t\t{0} = {1}", children.Guid, parentGuid); } } writer.WriteLine("\tEndGlobalSection"); writer.WriteLine("EndGlobal"); } } }