我已经开始直接使用MSBuild API来扩展构建过程并增加灵活性。为VC++使用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++项目的解决方案运行时,此方法完全落在它的表面上。原因是因为它无法解析可能位于道具文件(在上面详述的位置)内的INCLUDE路径。
另一个有趣的tid位是我可以直接从命令行复制参数到MSBuild,并且构建成功。这让我很困惑......所以我打开了详细的诊断程序并再次运行我的测试用例。
从日志有趣的信息(日志已被修剪):
- 从命令行建筑
USERDOMAIN = [删除]
USERNAME = MyUserName输入
LOCALAPPDATA = C:\ Users \ MyUserName \ AppData \ Local
- 从API大厦
USERDOMAIN = [绝密]
USERNAME = BUILDMACHINE $
LOCALAPPDATA = C:\ WINDOWS \ system32 \设置\ systemprofile \应用程序数据\本地
正如您所看到的,似乎从CLI构建时的当前身份正确设置为我的身份。但是,使用API进行构建可将当前身份设置为本地系统。这导致INCLUDE路径未正确设置为API构建,因为具有该信息的props文件在预期位置(C:\ Windows \ system32 \ config \ systemprofile \ AppData \ Local)不可用。
我的解决方法似乎到目前为止工作是实际将所有道具文件从AppData位置移动到API所期望的目录中。我不认为这是预期的行为...它似乎不是很清楚。
其他注意事项:
- 这段代码被托管在IIS,运行为“MyUserName输入”(而不是本地系统)的应用程序池中。
- 我已经能够重现上两台不同的机器都运行Windows Server 2008
这个问题无论是我错误地做一些事情,或MSBuild的API被错误地做什么?任何有关获取MSBuild API所识别的道具文件的官方手段的输入都会非常有用。
谢谢。