【问题标题】:Enforce Microsoft.Build to reload the project强制 Microsoft.Build 重新加载项目
【发布时间】:2022-08-08 19:35:29
【问题描述】:

我正在尝试迭代(自动化的一部分):

  • 在解决方案中创建项目的备份(文件系统上的物理文件)
  • 使用 Microsoft.Build 以编程方式加载和更改解决方案内部的项目(引用、包含、一些其他属性)
  • 使用控制台调用 msbuild 构建它
  • 恢复项目(从备份中物理覆盖已修补的版本)

这种方法适用于第一次迭代,但第二次似乎它不会加载恢复的项目并尝试使用我在第一次迭代中修补的值。看起来项目已被缓存:在 csproj 文件中我看到了正确的值,但在代码上我看到了以前修补过的值。 我最好的猜测是 Microsoft.Build 在当前进程的上下文中缓存解决方案/项目。

这是负责加载项目并调用方法以更新项目信息的代码:

private static void ForEachProject(string slnPath, Func<ProjectRootElement> patchProject)
{
    SolutionFile slnFile = SolutionFile.Parse(slnPath);
        var filtredProjects = slnFile
            .ProjectsInOrder
            .Where(prj => prj.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat);

        foreach (ProjectInSolution projectInfo in filtredProjects)
        {
            try
            {
                ProjectRootElement project = ProjectRootElement.Open(projectInfo.AbsolutePath);
                patchProject(project);
                project.Save();
            }
            catch (InvalidProjectFileException ex)
            {
                Console.WriteLine(\"Failed to patch project \'{0}\' with error: {1}\", projectInfo.AbsolutePath, ex);
            }
        }
}

    标签: microsoft.build


    【解决方案1】:

    ProjectRootElement 的 Reload 方法可以在与项目内容进行迭代之前调用。 它将强制 Microsoft.Build 从文件中读取最新信息。

    对我有用的代码:

    private static void ForEachProject(string slnPath, Func<ProjectRootElement> patchProject)
    {
        SolutionFile slnFile = SolutionFile.Parse(slnPath);
            var filtredProjects = slnFile
                .ProjectsInOrder
                .Where(prj => prj.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat);
    
            foreach (ProjectInSolution projectInfo in filtredProjects)
            {
                try
                {
                    ProjectRootElement project = ProjectRootElement.Open(projectInfo.AbsolutePath);
                    project.Reload(false); // Ignore cached state, read actual from the file
                    patchProject(project);
                    project.Save();
                }
                catch (InvalidProjectFileException ex)
                {
                    Console.WriteLine("Failed to patch project '{0}' with error: {1}", projectInfo.AbsolutePath, ex);
                }
            }
    }
    

    注意:最好在项目内部使用custom properties 并为每个 msbuild 调用提供它,而不是物理项目修补。请认为它是更好的解决方案并尽可能使用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-16
      • 1970-01-01
      • 2012-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-05
      • 2020-12-27
      相关资源
      最近更新 更多