internal static void WriteProjectXml( IInterpreterOptionsService service, TextWriter writer, string projectPath, string sourcePath, string filters, string searchPaths, string startupFile, PythonInterpreterView selectedInterpreter, ProjectCustomization customization, bool detectVirtualEnv ) { var projectHome = CommonUtils.GetRelativeDirectoryPath(Path.GetDirectoryName(projectPath), sourcePath); var project = ProjectRootElement.Create(); project.DefaultTargets = "Build"; project.ToolsVersion = "4.0"; var globals = project.AddPropertyGroup(); globals.AddProperty("Configuration", "Debug").Condition = " '$(Configuration)' == '' "; globals.AddProperty("SchemaVersion", "2.0"); globals.AddProperty("ProjectGuid", Guid.NewGuid().ToString("B")); globals.AddProperty("ProjectHome", projectHome); if (CommonUtils.IsValidPath(startupFile)) { globals.AddProperty("StartupFile", startupFile); } else { globals.AddProperty("StartupFile", ""); } globals.AddProperty("SearchPath", searchPaths); globals.AddProperty("WorkingDirectory", "."); globals.AddProperty("OutputPath", "."); globals.AddProperty("ProjectTypeGuids", "{888888a0-9f3d-457c-b088-3a5042f75d52}"); globals.AddProperty("LaunchProvider", DefaultLauncherProvider.DefaultLauncherName); var interpreterId = globals.AddProperty(PythonConstants.InterpreterId, ""); var interpreterVersion = globals.AddProperty(PythonConstants.InterpreterVersion, ""); if (selectedInterpreter != null && selectedInterpreter.Id != Guid.Empty) { interpreterId.Value = selectedInterpreter.Id.ToString("B"); interpreterVersion.Value = selectedInterpreter.Version.ToString(); } // VS requires property groups with conditions for Debug // and Release configurations or many COMExceptions are // thrown. var debugGroup = project.AddPropertyGroup(); var releaseGroup = project.AddPropertyGroup(); debugGroup.Condition = "'$(Configuration)' == 'Debug'"; releaseGroup.Condition = "'$(Configuration)' == 'Release'"; var folders = new HashSet <string>(); var virtualEnvPaths = detectVirtualEnv ? new List <string>() : null; foreach (var unescapedFile in EnumerateAllFiles(sourcePath, filters, virtualEnvPaths)) { var file = ProjectCollection.Escape(unescapedFile); var ext = Path.GetExtension(file); var fileType = "Content"; if (PythonConstants.FileExtension.Equals(ext, StringComparison.OrdinalIgnoreCase) || PythonConstants.WindowsFileExtension.Equals(ext, StringComparison.OrdinalIgnoreCase)) { fileType = "Compile"; } folders.Add(Path.GetDirectoryName(file)); project.AddItem(fileType, file); } foreach (var folder in folders.Where(s => !string.IsNullOrWhiteSpace(s)).OrderBy(s => s)) { project.AddItem("Folder", folder); } if (selectedInterpreter != null && selectedInterpreter.Id != Guid.Empty) { project.AddItem( MSBuildProjectInterpreterFactoryProvider.InterpreterReferenceItem, string.Format("{0:B}\\{1}", selectedInterpreter.Id, selectedInterpreter.Version) ); } if (virtualEnvPaths != null && virtualEnvPaths.Any() && service != null) { foreach (var options in virtualEnvPaths.Select(p => VirtualEnv.FindInterpreterOptions(p, service))) { AddVirtualEnvironment(project, sourcePath, options); if (string.IsNullOrEmpty(interpreterId.Value)) { interpreterId.Value = options.IdString; interpreterVersion.Value = options.LanguageVersionString; } } } var imports = project.AddPropertyGroup(); imports.AddProperty("VisualStudioVersion", "10.0").Condition = " '$(VisualStudioVersion)' == '' "; (customization ?? DefaultProjectCustomization.Instance).Process( project, new Dictionary <string, ProjectPropertyGroupElement> { { "Globals", globals }, { "Imports", imports }, { "Debug", debugGroup }, { "Release", releaseGroup } } ); project.Save(writer); }