引用 SSDT 项目的 WiX 项目无法在 TFSBuild 中构建 - 未定义的预处理器变量“$(var.DatabaseProject.TargetDir)”

Posted

技术标签:

【中文标题】引用 SSDT 项目的 WiX 项目无法在 TFSBuild 中构建 - 未定义的预处理器变量“$(var.DatabaseProject.TargetDir)”【英文标题】:WiX project that references an SSDT project fails to build in TFSBuild - Undefined preprocessor variable '$(var.DatabaseProject.TargetDir)' 【发布时间】:2013-04-17 21:02:43 【问题描述】:

作为更大解决方案一部分的我的项目已从 dbproj 转换为 asqlproj (SSDT)。该解决方案包括一个引用 SSDT 项目的 WiX 安装程序。 WiX 项目通过 VS2010 在多个开发者系统上构建良好。然而,我们一直使用的自动化构建失败并出现以下错误:

error CNDL0150: Undefined preprocessor variable '$(var.DatabaseProject.TargetDir)'.

在转换此项目之前,该解决方案已由 TFS 自动构建构建了数月,没有出现任何问题。我可以从构建日志中看到 SSDT 项目正在构建中,以下是构建日志中的一些相关行:

Project "C:\B\1\SourcePath\Server\Server.wixproj" (8) is building "C:\B\1\SourcePath\Database\DatabaseProject.sqlproj" (12) on node 1 (default targets).
...
Done Building Project "C:\B\1\SourcePath\Database\DatabaseProject.sqlproj" (default targets).

我还可以看到数据库项目的 .dacpac 和 .dll 文件已创建并复制到 TFS 构建已将项目重定向到的输出目录中。

对数据库项目的引用似乎很好,TFS 构建似乎知道应该构建它,但 WiX 抱怨 TargetDir 的未定义预处理器变量。

我一定是遗漏了什么... TFS 使用的输出重定向是否会导致我的问题?我不知道从哪里开始,感谢您提出的任何帮助。

更多信息

更详细地查看构建的日志文件,我可以看到.sqlproj 项目的参数没有通过命令行传递给candle.exe。当我在VS2010本地构建时,可以看到传递的预期参数如下(就像WiX项目引用的其他项目一样):

-d"DatabaseProject.FullConfiguration=Release|AnyCPU"
-dDatabaseProject.Platform=AnyCPU
-dDatabaseProject.ProjectDir=C:\SourcePath\Database\
-dDatabaseProject.ProjectExt=.sqlproj
-dDatabaseProject.ProjectFileName=DatabaseProject.sqlproj
-dDatabaseProject.ProjectName=DatabaseProject
-dDatabaseProject.ProjectPath=C:\SourcePath\Database\DatabaseProject.sqlproj
-dDatabaseProject.TargetDir=C:\SourcePath\Database\sql\release\
-dDatabaseProject.TargetExt=.dll
-dDatabaseProject.TargetFileName=DatabaseProject.dll
-dDatabaseProject.TargetName=DatabaseProject
-dDatabaseProject.TargetPath=C:\SourcePath\Database\sql\release\DatabaseProject.dll

在 TFS 构建期间,这些参数均未传递给 candle.exe。我认为这些信息可能有助于回答问题。

非常感谢任何帮助!

【问题讨论】:

我的设置几乎完全相同,它在 TFS 上运行良好。我能看到的唯一区别是我们使用的是 VS/TFS2012。我还记得必须从头开始重新创建 sqlproj,而不是进行升级,但不记得为什么。 @caveman_dick 感谢您的评论...我尝试从头开始重新创建项目,但仍然无法使用预处理器变量构建 WiX 项目。也许与 2012 年不同... 【参考方案1】:

根据@RobMenching 的回答,您将无法依赖任何命令行构建设置的 SSDT 项目变量,因此您需要找到另一种方法来引用项目的输出。

幸运的是,在标准 TFS 构建中,在给定构建配置中,所有项目的输出文件夹都是相同的。假设您没有以某种方式重定向输出,您应该能够使用任何其他项目(正常工作)作为参考路径。例如,假设您在解决方案中有 DatabaseProject.sqlprojDataAccessProject.csproj,您应该能够:

<Component Id='MyComponent' Guid='12345678-1234-1234-1234-123456789012'>
    <?ifdef DatabaseProject.TargetDir ?>
        <File Id='foo' Name='foo' src='$(var.DatabaseProject.TargetDir)\foo.dacpac' />
    <?else?>
        <File Id='foo' Name='foo' src='$(var.DataAccessProject.TargetDir)\foo.dacpac' />
    <?endif?>
</Component>

对于在 VS2010 中完成的构建,每个项目都构建到自己的输出文件夹中,应该定义正确的预处理器变量,它将使用第一个选项。对于未定义预处理器变量的 TFS 构建,TFS 会将 SSDT 的输出重定向到与所有其他项目相同的文件夹,因此任何一个预处理器变量都应该可以正常工作。

【讨论】:

感谢您的回答。我正在根据@RobMensching 的建议完成我的选择。我听从了您的建议,刚刚成功构建了 TFS。谢谢!【参考方案2】:

我认为这里的根本问题是.sqlproj 不支持必要的 Visual Studio 集成来为预处理器变量提供数据。多年来,这给 WiX 工具集带来了很多问题。不幸的是,修复它需要.sqlproj 的所有者修复他们的项目系统。

【讨论】:

奇怪的是它只适用于 TFS 自动构建。我能够在我的本地开发机器上构建它并且预处理器变量被正确解释。有什么办法可以解决 TFS 的问题吗?我正在听从 Gert Drapers 对我的帖子 here 的回答中的建议,从我的 WiX 安装程序中取出 SqlPackage。我需要在 WiX 安装中安装 .sqlproj 输出才能正常工作。 我相信它只适用于 Visual Studio。命令行构建不起作用。我会想出一种不同的方式来引用文件。在 WiX 工具集中,我们使用一组通用的 .props/.targets 将我们的整个构建组织到众所周知的位置。这是相当多的定制,但对我们有用。

以上是关于引用 SSDT 项目的 WiX 项目无法在 TFSBuild 中构建 - 未定义的预处理器变量“$(var.DatabaseProject.TargetDir)”的主要内容,如果未能解决你的问题,请参考以下文章

在 SQL Server 2012 SSDT 解决方案中引用 CLR 项目

SSDT 数据库项目中对系统数据库的引用变得重复

无法使用视图定义中具有表的完全限定名称的视图编译 SSDT 数据库项目

SSDT 很长时间加载项目和未解决的参考

Microsoft SSDT (10.3.21208.0)/数据层项目 (MSVS 2010) 和项目与引用数据库项目之间的“共享”/复制证书

sqlproj post-build $(Configuration) 在 TFS 上不正确