Exemplo n.º 1
0
 /// <summary>
 /// Generates a Visual Studio (c) Solution file.
 /// </summary>
 /// <param name="programArguments">The <see cref="ProgramArguments" /> to use when generating the solution.</param>
 /// <param name="logger">An optional <see cref="ISlnGenLogger" /> to use for logging.</param>
 /// <returns>zero if it the solution was generated, otherwise non-zero.</returns>
 public static int Generate(ProgramArguments programArguments, ISlnGenLogger logger = null)
 {
     using (SolutionFileGenerator solutionFileGenerator = new SolutionFileGenerator(programArguments, logger))
     {
         return(solutionFileGenerator.Generate());
     }
 }
Exemplo n.º 2
0
        public static ProjectCollection LoadProjectsAndReferences(
            IDictionary <string, string> globalProperties,
            string toolsVersion,
            IBuildEngine buildEngine,
            bool collectStats,
            string projectFullPath,
            IEnumerable <ITaskItem> projectReferences,
            ISlnGenLogger logger)
        {
            // Create an MSBuildProject loader with the same global properties of the project that requested a solution file
            MSBuildProjectLoader projectLoader = new MSBuildProjectLoader(globalProperties, toolsVersion, buildEngine, ProjectLoadSettings.IgnoreMissingImports)
            {
                CollectStats = collectStats,
            };

            logger.LogMessageHigh("Loading project references...");

            ProjectCollection projectCollection = projectLoader.LoadProjectsAndReferences(projectReferences.Select(i => i.GetMetadata("FullPath")).Concat(new[] { projectFullPath }));

            logger.LogMessageNormal($"Loaded {projectCollection.LoadedProjects.Count} project(s)");

            if (collectStats)
            {
                LogStatistics(projectLoader, logger);
            }

            return(projectCollection);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Gets the solution items' full paths.
        /// </summary>
        /// <param name="project">The <see cref="Project" /> containing the solution items.</param>
        /// <param name="logger">A <see cref="ISlnGenLogger" /> to use for logging.</param>
        /// <param name="fileExists">A <see cref="Func{String, Boolean}"/> to use when determining if a file exists.</param>
        /// <exception cref="ArgumentNullException"><paramref name="project" /> is null
        /// -or-
        /// <paramref name="logger" /> is null
        /// -or-
        /// <paramref name="fileExists" /> is null.</exception>
        /// <returns>An <see cref="IEnumerable{String}"/> of full paths to include as solution items.</returns>
        internal static IEnumerable <string> GetSolutionItems(Project project, ISlnGenLogger logger, Func <string, bool> fileExists = null)
        {
            if (project == null)
            {
                throw new ArgumentNullException(nameof(project));
            }

            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            fileExists ??= File.Exists;

            foreach (string solutionItem in project.GetItems(MSBuildItemNames.SlnGenSolutionItem).Select(i => i.GetMetadataValue("FullPath")).Where(i => !i.IsNullOrWhiteSpace()))
            {
                if (!fileExists(solutionItem))
                {
                    logger.LogMessageLow($"The solution item \"{solutionItem}\" does not exist and will not be added to the solution.", MessageImportance.Low);
                }
                else
                {
                    yield return(solutionItem);
                }
            }
        }
Exemplo n.º 4
0
        public static void GenerateSolutionFile(
            ProjectCollection projectCollection,
            string solutionFileFullPath,
            string projectFileFullPath,
            IReadOnlyDictionary <string, Guid> customProjectTypeGuids,
            bool folders,
            IEnumerable <string> solutionItems,
            ISlnGenLogger logger)
        {
            if (string.IsNullOrWhiteSpace(solutionFileFullPath))
            {
                solutionFileFullPath = Path.ChangeExtension(projectFileFullPath, ".sln");
            }

            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();

            solution.AddProjects(projectCollection, customProjectTypeGuids, projectFileFullPath);

            solution.AddSolutionItems(solutionItems);

            solution.Save(solutionFileFullPath, folders);
        }
Exemplo n.º 5
0
        public static void LogStatistics(MSBuildProjectLoader projectLoader, ISlnGenLogger logger)
        {
            logger.LogMessageLow("SlnGen Project Evaluation Performance Summary:");

            foreach (KeyValuePair <string, TimeSpan> item in projectLoader.Statistics.ProjectLoadTimes.OrderByDescending(i => i.Value))
            {
                logger.LogMessageLow($"  {Math.Round(item.Value.TotalMilliseconds, 0)} ms  {item.Key}", MessageImportance.Low);
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Creates an appropriate instance of a class that implements <see cref="IProjectLoader" />.
        /// </summary>
        /// <param name="msbuildExePath">The full path to MSBuild.exe.</param>
        /// <param name="logger">An <see cref="ISlnGenLogger" /> object to use for logging.</param>
        /// <returns>An <see cref="IProjectLoader" /> object that can be used to load MSBuild projects.</returns>
        public static IProjectLoader Create(FileInfo msbuildExePath, ISlnGenLogger logger)
        {
#if !NET46
            FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(msbuildExePath.FullName);

            // MSBuild 16.4 and above use the Static Graph API
            if (fileVersionInfo.FileMajorPart >= 16 && fileVersionInfo.FileMinorPart >= 4)
            {
                return(new ProjectGraphProjectLoader(logger));
            }
#endif

            return(new LegacyProjectLoader(logger));
        }
Exemplo n.º 7
0
        /// <summary>
        /// Creates an appropriate instance of a class that implements <see cref="IProjectLoader" />.
        /// </summary>
        /// <param name="msbuildExePath">The full path to MSBuild.exe.</param>
        /// <param name="logger">An <see cref="ISlnGenLogger" /> object to use for logging.</param>
        /// <returns>An <see cref="IProjectLoader" /> object that can be used to load MSBuild projects.</returns>
        private static IProjectLoader Create(FileInfo msbuildExePath, ISlnGenLogger logger)
        {
#if !NETFRAMEWORK
            return(new ProjectGraphProjectLoader(logger));
#elif NET461
            return(new LegacyProjectLoader(logger));
#else
            FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(msbuildExePath.FullName);

            // MSBuild 16.4 and above use the Static Graph API
            if (fileVersionInfo.FileMajorPart > 16 || (fileVersionInfo.FileMajorPart == 16 && fileVersionInfo.FileMinorPart >= 4))
            {
                return(new ProjectGraphProjectLoader(logger));
            }

            return(new LegacyProjectLoader(logger));
#endif
        }
Exemplo n.º 8
0
        private SolutionFileGenerator(ProgramArguments programArguments, ISlnGenLogger logger)
        {
            _programArguments = programArguments ?? throw new ArgumentNullException(nameof(programArguments));

            _logger = logger ?? new ForwardingLogger(GetLoggers().ToArray());

            _projectCollection = new ProjectCollection(
                globalProperties: null,
                loggers: new List <ILogger>
            {
                _logger as ILogger,
            },
                remoteLoggers: null,
                toolsetDefinitionLocations: ToolsetDefinitionLocations.Default,
                maxNodeCount: 1,
                onlyLogCriticalEvents: false,
                loadProjectsReadOnly: true);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Gets specified projects or all projects in the current working directory.
        /// </summary>
        /// <returns>An <see cref="IEnumerable{String}" /> containing the full paths to projects to generate a solution for.</returns>
        private IEnumerable <string> GetEntryProjectPaths(ISlnGenLogger logger)
        {
            if (_arguments.Projects == null || !_arguments.Projects.Any())
            {
                logger.LogMessageNormal("Searching \"{0}\" for projects", Environment.CurrentDirectory);
                bool projectFound = false;

                foreach (string projectPath in Directory.EnumerateFiles(Environment.CurrentDirectory, "*.*proj"))
                {
                    projectFound = true;

                    logger.LogMessageNormal("Generating solution for project \"{0}\"", projectPath);

                    yield return(projectPath);
                }

                if (!projectFound)
                {
                    logger.LogError("No projects found in the current directory. Please specify the path to the project you want to generate a solution for.");
                }

                yield break;
            }

            foreach (string projectPath in _arguments.Projects.Select(Path.GetFullPath))
            {
                if (!File.Exists(projectPath))
                {
                    logger.LogError(string.Format("Project file \"{0}\" does not exist", projectPath));
                    continue;
                }

                logger.LogMessageNormal("Generating solution for project \"{0}\"", projectPath);

                yield return(projectPath);
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// Logs a <see cref="ProjectStartedEventArgs" /> object for the specified project.
        /// </summary>
        /// <param name="logger">An <see cref="ISlnGenLogger" /> to use.</param>
        /// <param name="projectInstance">The <see cref="ProjectInstance" /> of the project.</param>
        internal static void LogProjectStartedEvent(ISlnGenLogger logger, ProjectInstance projectInstance)
        {
            if (!logger.IsDiagnostic)
            {
                return;
            }

            int projectId = logger.NextProjectId;

            logger.LogEvent(new ProjectStartedEventArgs(
                                projectId: projectId,
                                message: $"Project \"{projectInstance.FullPath}\"",
                                helpKeyword: null,
                                projectFile: projectInstance.FullPath,
                                targetNames: null,
                                properties: projectInstance.Properties.Select(i => new DictionaryEntry(i.Name, i.EvaluatedValue)),
                                items: projectInstance.Items.Select(i => new DictionaryEntry(i.ItemType, new ProjectItemWrapper(i))),
                                parentBuildEventContext: BuildEventContext.Invalid,
                                globalProperties: projectInstance.GlobalProperties,
                                toolsVersion: null)
            {
                BuildEventContext = new BuildEventContext(BuildEventContext.InvalidSubmissionId, BuildEventContext.InvalidNodeId, projectInstance.EvaluationId, projectId, projectId, BuildEventContext.InvalidTargetId, BuildEventContext.InvalidTaskId),
            });
        }
Exemplo n.º 11
0
        private (TimeSpan projectEvaluation, int projectCount) LoadProjects(ProjectCollection projectCollection, ISlnGenLogger logger)
        {
            List <string> entryProjects = GetEntryProjectPaths(logger).ToList();

            if (logger.HasLoggedErrors)
            {
                return(TimeSpan.Zero, 0);
            }

            logger.LogMessageHigh("Loading project references...");

            Stopwatch sw = Stopwatch.StartNew();

            IProjectLoader projectLoader = ProjectLoaderFactory.Create(_msbuildExePath, logger);

            IDictionary <string, string> globalProperties = GetGlobalProperties();

            using (new MSBuildFeatureFlags
            {
                CacheFileEnumerations = true,
                LoadAllFilesAsReadOnly = true,
                MSBuildSkipEagerWildCardEvaluationRegexes = true,
                UseSimpleProjectRootElementCacheConcurrency = true,
                MSBuildExePath = _msbuildExePath.FullName,
            })
            {
                try
                {
                    projectLoader.LoadProjects(entryProjects, projectCollection, globalProperties);
                }
                catch (InvalidProjectFileException)
                {
                    return(TimeSpan.Zero, 0);
                }
                catch (Exception e)
                {
                    logger.LogError(e.ToString());
                    return(TimeSpan.Zero, 0);
                }
            }

            sw.Stop();

            logger.LogMessageNormal($"Loaded {projectCollection.LoadedProjects.Count:N0} project(s) in {sw.ElapsedMilliseconds:N0}ms");

            return(sw.Elapsed, projectCollection.LoadedProjects.Count);
        }
Exemplo n.º 12
0
 /// <summary>
 /// Initializes a new instance of the <see cref="LegacyProjectLoader"/> class.
 /// </summary>
 /// <param name="logger">An <see cref="ISlnGenLogger" /> to use for logging.</param>
 public LegacyProjectLoader(ISlnGenLogger logger)
 {
     _logger = logger ?? throw new ArgumentNullException(nameof(logger));
 }
Exemplo n.º 13
0
 /// <summary>
 /// Creates an appropriate instance of a class that implements <see cref="IProjectLoader" />.
 /// </summary>
 /// <param name="logger">An <see cref="ISlnGenLogger" /> object to use for logging.</param>
 /// <returns>An <see cref="IProjectLoader" /> object that can be used to load MSBuild projects.</returns>
 private static IProjectLoader Create(ISlnGenLogger logger)
Exemplo n.º 14
0
        /// <summary>
        /// Loads projects.
        /// </summary>
        /// <param name="msbuildExeFileInfo">The <see cref="FileInfo" /> of MSBuild.exe.</param>
        /// <param name="projectCollection">The <see cref="ProjectCollection" /> to use when loading projects.</param>
        /// <param name="entryProjects">The <see cref="IEnumerable{String}" /> of entry projects.</param>
        /// <param name="globalProperties">The <see cref="IDictionary{String,String}" /> of global properties to use.</param>
        /// <param name="logger">A <see cref="ISlnGenLogger" /> to use as a logger.</param>
        /// <returns>A <see cref="Tuple{TimeSpan, Int32}" /> with the amount of time it took to load projects and the total number of projects that were loaded.</returns>
        public static (TimeSpan projectEvaluation, int projectCount) LoadProjects(FileInfo msbuildExeFileInfo, ProjectCollection projectCollection, IEnumerable <string> entryProjects, IDictionary <string, string> globalProperties, ISlnGenLogger logger)
        {
            if (logger.HasLoggedErrors)
            {
                return(TimeSpan.Zero, 0);
            }

            logger.LogMessageHigh("Loading project references...");

            Stopwatch sw = Stopwatch.StartNew();

#if NET472
            IProjectLoader projectLoader = Create(msbuildExeFileInfo, logger);
#else
            IProjectLoader projectLoader = Create(logger);
#endif

            try
            {
                projectLoader.LoadProjects(entryProjects, projectCollection, globalProperties);
            }
            catch (InvalidProjectFileException)
            {
                return(TimeSpan.Zero, 0);
            }
            catch (Exception e)
            {
                logger.LogError(e.ToString());
                return(TimeSpan.Zero, 0);
            }

            sw.Stop();

            logger.LogMessageNormal($"Loaded {projectCollection.LoadedProjects.Count:N0} project(s) in {sw.ElapsedMilliseconds:N0}ms");

            return(sw.Elapsed, projectCollection.LoadedProjects.Count);
        }
Exemplo n.º 15
0
        /// <summary>
        /// Gets the solution items' full paths.
        /// </summary>
        /// <param name="items">The <see cref="IEnumerable{IMSBuildItem}" /> containing the solution items.</param>
        /// <param name="logger">A <see cref="ISlnGenLogger" /> to use for logging.</param>
        /// <param name="fileExists">A <see cref="Func{String, Boolean}"/> to use when determining if a file exists.</param>
        /// <exception cref="ArgumentNullException"><paramref name="items" /> is <code>null</code>
        /// -or-
        /// <paramref name="logger" /> is <code>null</code>
        /// -or-
        /// <paramref name="fileExists" /> is <code>null</code>.</exception>
        /// <returns>An <see cref="IEnumerable{String}"/> of full paths to include as solution items.</returns>
        internal static IEnumerable <string> GetSolutionItems(IEnumerable <IMSBuildItem> items, ISlnGenLogger logger, Func <string, bool> fileExists)
        {
            if (items == null)
            {
                throw new ArgumentNullException(nameof(items));
            }

            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            if (fileExists == null)
            {
                throw new ArgumentNullException(nameof(fileExists));
            }

            foreach (string solutionItem in items.Select(i => i.GetMetadata("FullPath")).Where(i => !string.IsNullOrWhiteSpace(i)))
            {
                if (!fileExists(solutionItem))
                {
                    logger.LogMessageLow($"The solution item \"{solutionItem}\" does not exist and will not be added to the solution.", MessageImportance.Low);
                }
                else
                {
                    yield return(solutionItem);
                }
            }
        }
Exemplo n.º 16
0
        /// <summary>
        /// Launches Visual Studio.
        /// </summary>
        /// <param name="solutionFileFullPath">The full path to the solution file.</param>
        /// <param name="loadProjects">A value indicating whether to load projects in Visual Studio.</param>
        /// <param name="devEnvFullPath">An optional full path to devenv.exe.</param>
        /// <param name="logger">A <see cref="ISlnGenLogger" /> to use for logging.</param>
        public static void Launch(string solutionFileFullPath, bool loadProjects, string devEnvFullPath, ISlnGenLogger logger)
        {
            if (solutionFileFullPath.IsNullOrWhiteSpace())
            {
                throw new ArgumentNullException(nameof(solutionFileFullPath));
            }

            CommandLineBuilder commandLineBuilder = new CommandLineBuilder();

            ProcessStartInfo processStartInfo;

            if (!devEnvFullPath.IsNullOrWhiteSpace())
            {
                if (!File.Exists(devEnvFullPath))
                {
                    logger.LogError($"The specified path to Visual Studio ({devEnvFullPath}) does not exist or is inaccessible.");

                    return;
                }

                processStartInfo = new ProcessStartInfo
                {
                    FileName        = devEnvFullPath,
                    UseShellExecute = false,
                };

                commandLineBuilder.AppendFileNameIfNotNull(solutionFileFullPath);

                if (!loadProjects)
                {
                    commandLineBuilder.AppendSwitch(DoNotLoadProjectsCommandLineArgument);
                }
            }
            else
            {
                processStartInfo = new ProcessStartInfo
                {
                    FileName        = solutionFileFullPath,
                    UseShellExecute = true,
                };
            }

            try
            {
                processStartInfo.Arguments = commandLineBuilder.ToString();

                Process process = new Process
                {
                    StartInfo = processStartInfo,
                };

                logger.LogMessageHigh("Launching Visual Studio...");
                logger.LogMessageLow("  FileName = {0}", processStartInfo.FileName);
                logger.LogMessageLow("  Arguments = {0}", processStartInfo.Arguments);
                logger.LogMessageLow("  UseShellExecute = {0}", processStartInfo.UseShellExecute);
                logger.LogMessageLow("  WindowStyle = {0}", processStartInfo.WindowStyle);

                if (!process.Start())
                {
                    logger.LogError("Failed to launch Visual Studio.");
                }
            }
            catch (Exception e)
            {
                logger.LogError($"Failed to launch Visual Studio. {e.Message}");
            }
        }
Exemplo n.º 17
0
        public static void LaunchVisualStudio(string devEnvFullPath, bool useShellExecute, string solutionFileFullPath, ISlnGenLogger logger)
        {
            ProcessStartInfo processStartInfo;

            if (!string.IsNullOrWhiteSpace(devEnvFullPath))
            {
                if (!File.Exists(devEnvFullPath))
                {
                    logger.LogError($"The specified path to Visual Studio ({devEnvFullPath}) does not exist or is inaccessible.");

                    return;
                }

                processStartInfo = new ProcessStartInfo
                {
                    FileName  = devEnvFullPath,
                    Arguments = $"\"{solutionFileFullPath}\"",
                };
            }
            else if (!useShellExecute)
            {
                processStartInfo = new ProcessStartInfo
                {
                    Arguments   = $"/C start \"\" \"devenv.exe\" \"{solutionFileFullPath}\"",
                    FileName    = Environment.GetEnvironmentVariable("ComSpec"),
                    WindowStyle = ProcessWindowStyle.Hidden,
                };
            }
            else
            {
                processStartInfo = new ProcessStartInfo
                {
                    FileName        = solutionFileFullPath,
                    UseShellExecute = true,
                };
            }

            try
            {
                Process process = new Process
                {
                    StartInfo = processStartInfo,
                };

                logger.LogMessageHigh("Opening Visual Studio solution...");
                logger.LogMessageLow("  FileName = {0}", processStartInfo.FileName);
                logger.LogMessageLow("  Arguments = {0}", processStartInfo.Arguments);
                logger.LogMessageLow("  UseShellExecute = {0}", processStartInfo.UseShellExecute);
                logger.LogMessageLow("  WindowStyle = {0}", processStartInfo.WindowStyle);

                if (!process.Start())
                {
                    logger.LogError("Failed to launch Visual Studio.");
                }
            }
            catch (Exception e)
            {
                logger.LogError($"Failed to launch Visual Studio. {e.Message}");
            }
        }
Exemplo n.º 18
0
        /// <summary>
        /// Launches Visual Studio.
        /// </summary>
        /// <param name="arguments">The current <see cref="ProgramArguments" />.</param>
        /// <param name="visualStudioInstance">A <see cref="VisualStudioInstance" /> object representing which instance of Visual Studio to launch.</param>
        /// <param name="solutionFileFullPath">The full path to the solution file.</param>
        /// <param name="logger">A <see cref="ISlnGenLogger" /> to use for logging.</param>
        /// <returns>true if Visual Studio was launched, otherwise false.</returns>
        public static bool TryLaunch(ProgramArguments arguments, VisualStudioInstance visualStudioInstance, string solutionFileFullPath, ISlnGenLogger logger)
        {
            if (!arguments.ShouldLaunchVisualStudio())
            {
                return(true);
            }

            if (!Utility.RunningOnWindows)
            {
                logger.LogWarning("Launching Visual Studio is not currently supported on your operating system.");

                return(true);
            }

            bool loadProjectsInVisualStudio = arguments.ShouldLoadProjectsInVisualStudio();
            bool enableShellExecute         = arguments.EnableShellExecute();

            string devEnvFullPath = arguments.DevEnvFullPath?.LastOrDefault();

            if (!enableShellExecute || !loadProjectsInVisualStudio || Program.CurrentDevelopmentEnvironment.IsCorext)
            {
                if (devEnvFullPath.IsNullOrWhiteSpace())
                {
                    if (visualStudioInstance == null)
                    {
                        logger.LogError(
                            Program.CurrentDevelopmentEnvironment.IsCorext
                                ? $"Could not find a Visual Studio {Environment.GetEnvironmentVariable("VisualStudioVersion")} installation.  Please do one of the following:\n a) Specify a full path to devenv.exe via the -vs command-line argument\n b) Update your corext.config to specify a version of MSBuild.Corext that matches a Visual Studio version you have installed\n c) Install a version of Visual Studio that matches the version of MSBuild.Corext in your corext.config"
                                : "Could not find a Visual Studio installation.  Please specify the full path to devenv.exe via the -vs command-line argument");

                        return(false);
                    }

                    if (visualStudioInstance.IsBuildTools)
                    {
                        logger.LogError("Cannot use a BuildTools instance of Visual Studio.");

                        return(false);
                    }

                    devEnvFullPath = Path.Combine(visualStudioInstance.InstallationPath, "Common7", "IDE", "devenv.exe");
                }
            }

            if (solutionFileFullPath.IsNullOrWhiteSpace())
            {
                throw new ArgumentNullException(nameof(solutionFileFullPath));
            }

            CommandLineBuilder commandLineBuilder = new CommandLineBuilder();

            ProcessStartInfo processStartInfo;

            if (!devEnvFullPath.IsNullOrWhiteSpace())
            {
                if (!File.Exists(devEnvFullPath))
                {
                    logger.LogError($"The specified path to Visual Studio ({devEnvFullPath}) does not exist or is inaccessible.");

                    return(false);
                }

                processStartInfo = new ProcessStartInfo
                {
                    FileName        = devEnvFullPath !,
                    UseShellExecute = false,
                };

                commandLineBuilder.AppendFileNameIfNotNull(solutionFileFullPath);

                if (!arguments.ShouldLoadProjectsInVisualStudio())
                {
                    commandLineBuilder.AppendSwitch(DoNotLoadProjectsCommandLineArgument);
                }
            }
            else
            {
                processStartInfo = new ProcessStartInfo
                {
                    FileName        = solutionFileFullPath,
                    UseShellExecute = true,
                };
            }

            try
            {
                processStartInfo.Arguments = commandLineBuilder.ToString();

                Process process = new Process
                {
                    StartInfo = processStartInfo,
                };

                logger.LogMessageHigh("Launching Visual Studio...");
                logger.LogMessageLow("  FileName = {0}", processStartInfo.FileName);
                logger.LogMessageLow("  Arguments = {0}", processStartInfo.Arguments);
                logger.LogMessageLow("  UseShellExecute = {0}", processStartInfo.UseShellExecute);
                logger.LogMessageLow("  WindowStyle = {0}", processStartInfo.WindowStyle);

                if (!process.Start())
                {
                    logger.LogError("Failed to launch Visual Studio.");
                }
            }
            catch (Exception e)
            {
                logger.LogError($"Failed to launch Visual Studio. {e.Message}");
            }

            return(true);
        }
Exemplo n.º 19
0
 /// <summary>
 /// Gets the solution items' full paths.
 /// </summary>
 /// <param name="items">The <see cref="IEnumerable{IMSBuildItem}" /> containing the solution items.</param>
 /// <param name="logger">A <see cref="ISlnGenLogger" /> to use for logging.</param>
 /// <returns>An <see cref="IEnumerable{String}"/> of full paths to include as solution items.</returns>
 public static IEnumerable <string> GetSolutionItems(IEnumerable <IMSBuildItem> items, ISlnGenLogger logger)
 {
     return(GetSolutionItems(items, logger, File.Exists));
 }
Exemplo n.º 20
0
        /// <summary>
        /// Generates a solution file.
        /// </summary>
        /// <param name="arguments">The current <see cref="ProgramArguments" />.</param>
        /// <param name="projects">A <see cref="IEnumerable{String}" /> containing the entry projects.</param>
        /// <param name="logger">A <see cref="ISlnGenLogger" /> to use for logging.</param>
        /// <returns>A <see cref="Tuple{String, Int32, Int32, Guid}" /> with the full path to the solution file, the count of custom project type GUIDs used, the count of solution items, and the solution GUID.</returns>
        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 (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);

            solution.Save(solutionFileFullPath, arguments.EnableFolders(), arguments.EnableCollapseFolders());

            return(solutionFileFullPath, customProjectTypeGuids.Count, solutionItems.Count, solution.SolutionGuid);
        }
Exemplo n.º 21
0
 /// <summary>
 /// Creates an appropriate instance of a class that implements <see cref="IProjectLoader" />.
 /// </summary>
 /// <param name="msbuildExePath">The full path to MSBuild.exe.</param>
 /// <param name="logger">An <see cref="ISlnGenLogger" /> object to use for logging.</param>
 /// <returns>An <see cref="IProjectLoader" /> object that can be used to load MSBuild projects.</returns>
 private static IProjectLoader Create(FileInfo msbuildExePath, ISlnGenLogger logger)
 /// <summary>
 /// Initializes a new instance of the <see cref="ProjectGraphProjectLoader"/> class.
 /// </summary>
 /// <param name="logger">An <see cref="ISlnGenLogger" /> to use for logging.</param>
 public ProjectGraphProjectLoader(ISlnGenLogger logger)
 {
     _logger = logger;
 }
Exemplo n.º 23
0
        /// <summary>
        /// Launches Visual Studio.
        /// </summary>
        /// <param name="arguments">The current <see cref="ProgramArguments" />.</param>
        /// <param name="visualStudioInstance">A <see cref="VisualStudioInstance" /> object representing which instance of Visual Studio to launch.</param>
        /// <param name="solutionFileFullPath">The full path to the solution file.</param>
        /// <param name="logger">A <see cref="ISlnGenLogger" /> to use for logging.</param>
        /// <returns>true if Visual Studio was launched, otherwise false.</returns>
        public static bool TryLaunch(ProgramArguments arguments, VisualStudioInstance visualStudioInstance, string solutionFileFullPath, ISlnGenLogger logger)
        {
            if (!arguments.ShouldLaunchVisualStudio())
            {
                return(true);
            }

            if (!Utility.RunningOnWindows)
            {
                logger.LogWarning("Launching Visual Studio is not currently supported on your operating system.");

                return(true);
            }

            string devEnvFullPath = arguments.GetDevEnvFullPath(visualStudioInstance);

            if (!devEnvFullPath.IsNullOrWhiteSpace())
            {
                visualStudioInstance = VisualStudioConfiguration.GetInstanceForPath(devEnvFullPath);
            }

            if (visualStudioInstance == null)
            {
                logger.LogError(
                    Program.CurrentDevelopmentEnvironment.IsCorext
                        ? $"Could not find a Visual Studio {Environment.GetEnvironmentVariable("VisualStudioVersion")} installation.  Please do one of the following:\n a) Specify a full path to devenv.exe via the -vs command-line argument\n b) Update your corext.config to specify a version of MSBuild.Corext that matches a Visual Studio version you have installed\n c) Install a version of Visual Studio that matches the version of MSBuild.Corext in your corext.config"
                        : "Could not find a Visual Studio installation.  Please run from a command window that has MSBuild.exe on the PATH or specify the full path to devenv.exe via the -vs command-line argument");

                return(false);
            }

            if (visualStudioInstance.IsBuildTools)
            {
                logger.LogError("Cannot use a BuildTools instance of Visual Studio.");

                return(false);
            }

            if (!File.Exists(devEnvFullPath))
            {
                logger.LogError($"The specified path to Visual Studio ({devEnvFullPath}) does not exist or is inaccessible.");

                return(false);
            }

            CommandLineBuilder commandLineBuilder = new CommandLineBuilder();

            commandLineBuilder.AppendFileNameIfNotNull(solutionFileFullPath);

            if (!arguments.ShouldLoadProjectsInVisualStudio())
            {
                commandLineBuilder.AppendSwitch(DoNotLoadProjectsCommandLineArgument);
            }

            try
            {
                Process process = new Process
                {
                    StartInfo = new ProcessStartInfo
                    {
                        FileName        = devEnvFullPath,
                        Arguments       = commandLineBuilder.ToString(),
                        UseShellExecute = false,
                    },
                };

                logger.LogMessageHigh("Launching Visual Studio...");
                logger.LogMessageLow("  FileName = {0}", process.StartInfo.FileName);
                logger.LogMessageLow("  Arguments = {0}", process.StartInfo.Arguments);

                if (!process.Start())
                {
                    logger.LogError("Failed to launch Visual Studio.");
                }
            }
            catch (Exception e)
            {
                logger.LogError($"Failed to launch Visual Studio. {e.Message}");
            }

            return(true);
        }