Loading

C#使用Microsoft.Build完成项目处理和编译

1、使用Microsoft.Build进行项目编译

        static void Build()
        {
            // 项目文件路径
            string projectFilePath = @"C:\Users\97460\source\repos\ConsoleApp1\ConsoleApp1\ConsoleApp1.csproj";
          
            // 方式1
            Project project = new Project(projectFilePath);
            if (project.Build())
            {
                Console.WriteLine("编译成功!");
            }
            else
            {
                Console.WriteLine("编译失败");
            }

            // 方式2
            using (ProjectCollection projectCollection = new ProjectCollection())
            {
                // 编译结果日志输出文件
                string buildResultFilePath = @"logfile=C:\\1.txt";
                ILogger logger = new Microsoft.Build.Logging.FileLogger()
                {
                    Parameters = buildResultFilePath,
                };

                // 编译全局全量
                var globalProperty = new Dictionary<string, string>();
                globalProperty.Add("Configuration", "Debug");        
                globalProperty.Add("Platform", "AnyCPU");
               
                // 编译
                var buidlRequest = new BuildRequestData(projectFilePath, globalProperty, null, new string[] { "Build" }, null);
                var buildResult = BuildManager.DefaultBuildManager.Build(new BuildParameters(projectCollection)
                {
                    Loggers = new Collection<ILogger> { logger } 
                },buidlRequest);
                if (buildResult.OverallResult == BuildResultCode.Success)
                {
                    Console.WriteLine("编译成功!");
                }
                else
                {
                    Console.WriteLine("编译失败");
                }
            }
        }

2、使用devenv命令行进行编译

        static void BuildCmd()
        {
            // 添加devenv环境变量
            string vs2022 = "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\Common7\\IDE\\";
            var envirPaths = Environment.GetEnvironmentVariable("Path").Split(';');
            if (envirPaths.FirstOrDefault(e => e == vs2022) == null)
            {
                var newPath = $"{Environment.GetEnvironmentVariable("Path")};{vs2022}";
                Environment.SetEnvironmentVariable("Path", newPath);
            }

            // 项目文件路径
            string solutionFilePath = "C:\\Users\\97460\\source\\repos\\ConsoleApp1\\ConsoleApp1.sln";
            string projectFilePath = @"C:\Users\97460\source\repos\ConsoleApp1\ConsoleApp1\ConsoleApp1.csproj";
            var log = $"{Path.GetDirectoryName(visionMasterPath)}\\{Path.GetFileNameWithoutExtension(projectFilePath)}_Build.log";
            // 启动编译命令
            Process process = new Process();
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.WorkingDirectory = Path.GetDirectoryName(solutionFilePath);
            process.StartInfo.FileName = "cmd.exe";
            // 编译解决方案(Debug编译)
            process.StartInfo.Arguments = "/c " + $"devenv {solutionFilePath} /Build Debug";
            // 编译项目(Release|x86编译并输出编译日志)
            process.StartInfo.Arguments = "/c " +  $"devenv \"{visionMasterPath}\" /build \"release|x86\" /project \"{projectFilePath}\" /out \"{log}\"";
            process.StartInfo.RedirectStandardOutput = true;
            process.Start();
            var buildResultInfo = process.StandardOutput.ReadToEnd();
            process.WaitForExit();
            process.Close();
            Console.WriteLine(buildResultInfo);
        }

更多的devenv命令可阅读 Devenv 命令行开关 - Visual Studio (Windows) | Microsoft Learn
如果使用Relase|x86或者Relase|x64编译报错“命令无效”,请先检查待编译的工程是否配置该解决方案平台。

3、添加引用

static void AddRefence()
        {
            // 项目文件.csproj路径
            string prjectFilePath = @"C:\Users\97460\source\repos\WpfApp1\WpfApp1\WpfApp1.csproj";
            var project = new Project(prjectFilePath);

            Console.WriteLine("获取所有的DLL引用");
            var references = project.GetItems("Reference");
            Console.WriteLine(string.Join("\r\n", references.Select(p=>p.EvaluatedInclude)));

            Console.WriteLine("移除DLL引用");
            var dllProjectItem = references.FirstOrDefault(p => p.EvaluatedInclude == "ClassLibrary1");
            if (dllProjectItem != null)
            {
                references.Remove(dllProjectItem);
            }

            Console.WriteLine("添加新的DLL引用");
            var metadata = new List<KeyValuePair<string, string>>();
            // DLL文件相对于项目的相对路径
            metadata.Add(new KeyValuePair<string, string>("HintPath", "..\\ClassLibrary3\\bin\\Debug\\ClassLibrary2.dll"));
            // 是否复制本地
            metadata.Add(new KeyValuePair<string, string>("Private", "True"));
            project.AddItem("Reference", "ClassLibrary2", metadata);


            Console.WriteLine("获取所有的项目引用");
            var projectReferences = project.GetItems("ProjectReference");
            Console.WriteLine(string.Join("\r\n", projectReferences.Select(p => p.EvaluatedInclude)));

            Console.WriteLine("移除项目引用");
            var projectItem = references.FirstOrDefault(p => p.EvaluatedInclude == "ClassLibrary1");
            if (projectItem != null)
            {
                references.Remove(projectItem);
            }

            Console.WriteLine("添加新的项目引用");
            var metadata1 = new List<KeyValuePair<string, string>>();
            // 添加项目的GUID
            var addProject = new Project(@"C:\\Users\\97460\\source\\repos\\WpfApp1\\ClassLibrary3\ClassLibrary3.csproj");
            var guid = addProject.GetProperty("ProjectGuid").EvaluatedValue;
            metadata1.Add(new KeyValuePair<string, string>("Project", guid));
            // 项目名称
            metadata1.Add(new KeyValuePair<string, string>("Name", "ClassLibrary3"));
            project.AddItem("ProjectReference", "ClassLibrary3", metadata1);

            // 保存到本地
            project.Save();

        }

4、多次初始化Project遇到的问题

static void TestProject()
        {
            try
            {
                string prjectFilePath = @"C:\Users\97460\source\repos\WpfApp1\WpfApp1\WpfApp1.csproj";
                var project0 = new Project(prjectFilePath);
                var project1 = new Project(prjectFilePath);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

使用以上测试代码进行测试会报错:在项目集合中已有等效项目(全局属性和工具版本相同的项目),路径为“C:\Users\97460\source\repos\WpfApp1\WpfApp1\WpfApp1.csproj”。若要向此项目集合中加载等效项目,请先卸载此项目。

测试可以使用以下两种方式进行处理:

 static void TestProject()
        {
            try
            {
                string prjectFilePath = @"C:\Users\97460\source\repos\WpfApp1\WpfApp1\WpfApp1.csproj";
                var project0 = new Project(prjectFilePath);
                var projects = ProjectCollection.GlobalProjectCollection.LoadedProjects;
                Console.WriteLine("获取全局项目集合");
                Console.WriteLine(string.Join("\r\n", projects.Select(p => p.GetProperty("AssemblyName").EvaluatedValue)));
                var newProject = projects.FirstOrDefault(p => p.GetProperty("AssemblyName").EvaluatedValue == "WpfApp1");
                if (newProject != null)
                {
                    ProjectCollection.GlobalProjectCollection.UnloadProject(newProject);
                }

                var project1 = new Project(prjectFilePath);
                
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

此方法卸载的是本地缓存,重新加载后还是使用的是缓存里面的文件,因此此时外部文件更新,但加载的信息不会更新,没有特殊要求,可以使用下面第二种方法:

  static void TestProject1()
        {
            try
            {
                string prjectFilePath = @"C:\Users\97460\source\repos\WpfApp1\WpfApp1\WpfApp1.csproj";
                var project0 = new Project(prjectFilePath,null,null,new ProjectCollection());
                var project1 = new Project(prjectFilePath, null, null, new ProjectCollection());
                Console.WriteLine("连续多次加载成功!");

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
posted @ 2023-02-05 17:03  Dwaynerbing  阅读(170)  评论(0编辑  收藏  举报