0

我已经开始直接使用 MSBuild API 来扩展我们的构建过程并增加灵活性。

我已经成功地自动化了构建我们项目的整个过程,但并非没有一些“陷阱”。由于 MSBuild API 上极度缺乏文档和使用示例,我不得不忍受一些冗长的调试会话。

希望我在这里概述的详细信息将帮助其他希望直接与 MSBuild API 集成的人。

编译 C# 代码非常简单,但是一旦我尝试使用 MSBuild API 编译我们的一些遗留 VC++ 项目,这个过程就遇到了困难。

这是我的编译器包装器的代码示例:

            globalProperties["Configuration"] = CommonLibrary.BuildMode.Release.ToString();

            //add the compiler variables from the specific project to the properties dictionary
            if (compilerVariables != null)
            {
                foreach(var kvp in compilerVariables)
                {
                    globalProperties.Add(kvp.Key, kvp.Value);
                }
            }

            //set up a build request to be sent to MSBuild
            var request = new BuildRequestData(project.SolutionFile.FullName, globalProperties, null, new string[] { "Rebuild" }, null);

            //configure settings for MSBuild specifically
            var buildParams = new BuildParameters();
            buildParams.EnableNodeReuse = true;

            buildParams.Loggers = new List<Microsoft.Build.Framework.ILogger>() 
            {
                buildLogger,
                fileLogger
            };

            //instantiate the BuildManager, kick off the build, and get the results
            BuildManager buildManager = new BuildManager();
            project.BuildResult = buildManager.Build(buildParams, request);

此过程的另一个方面涉及 .props 文件,VC++ 使用该文件来获取链接器所需的 INCLUDE(和其他路径)。此 .props 文件位于 C:\Users\%BUILDACCOUNT%\AppData\Local\Microsoft\MSBuild\v4.0\Microsoft.Cpp.%TargetPlatform%.user.props

现在是有趣的部分。

当我针对 C# 项目/解决方案运行此代码时,一切正常。这是因为 .props 文件在 C# 编译中不起作用(包含路径存储为 .csproj 级别)。

但是,当针对包含 VC++ 项目的解决方案运行时,这种方法完全落空了。原因是它无法解析可能位于 props 文件中的 INCLUDE 路径(位于上面详述的位置)。

另一个有趣的花絮是我可以直接从命令行复制参数到 MSBuild,并且构建成功。这真的让我感到困惑......所以我打开了详细诊断并再次运行我的测试用例。

日志中的有趣信息(日志已被修剪):

  1. 从命令行构建

用户域 = [已编辑]

用户名 = 我的用户名

LOCALAPPDATA = C:\Users\MyUserName\AppData\Local

  1. 从 API 构建

用户域 = [已编辑]

用户名 = 建造机 $

LOCALAPPDATA = C:\Windows\system32\config\systemprofile\AppData\Local

如您所见,从 CLI 构建时的当前身份似乎已正确设置为我的身份。但是,从 API 构建会将当前身份设置为本地系统。这会导致没有为 API 构建正确设置 INCLUDE 路径,因为包含该信息的 props 文件在预期位置 (C:\Windows\system32\config\systemprofile\AppData\Local) 不可用。

到目前为止似乎有效的解决方法是将所有道具文件从 AppData 位置实际移动到 API 期望它所在的目录。我不认为这是预期的行为......它似乎不是非常易懂。

补充说明:

  • 此代码托管在 IIS 上,位于以“MyUserName”(不是本地系统)运行的应用程序池中。
  • 我已经能够在运行 Windows Server 2008 的两台不同机器上重现此问题

是我做错了什么,还是 MSBuild API 做错了什么?有关获取 MSBuild API 识别的 props 文件的官方方法的任何输入都将非常有帮助。

谢谢。

4

1 回答 1

1

好的,我已经弄清楚问题所在了。

该问题与 MSBuild 无关。相反,它与我的 IIS 配置有关。

尽管我的应用程序池以我的构建帐户的身份运行,但我选择了“Load User Profile = False”,这导致用户配置文件默认为 LocalSystem。

将此设置切换为“Load User Profile = True”修复了此问题,并且 MSBuild 开始访问正确的 .props 文件。

于 2013-04-29T16:31:20.870 回答