如何抑制MSBuild中找不到解决方案内外部EXE项目的警告
我有一个用于插件DLL的Visual Studio解决方案,VS本地构建完全正常。这个解决方案里包含一个用于调试的"项目",实际是对外部可执行文件Paratext.exe的引用,用作VS的启动项目,项目定义如下:
Project("{911E67C6-3D85-4FCE-B560-20A9C3E3FF48}") = "Paratext", "%ParatextInstallDir%\Paratext.exe", "{64795DCD-9F35-4E20-9A1F-888A6416329A}" ProjectSection(DebuggerProjectSystem) = preProject PortSupplier = 00000000-0000-0000-0000-000000000000 Executable = %ParatextInstallDir%\Paratext.exe RemoteMachine = LSDEV-TBOGLE StartingDirectory = %ParatextInstallDir% Environment = Default LaunchingEngine = fb0d4648-f776-4980-95f8-bb7f36ebc1ee UseLegacyDebugEngines = No LaunchSQLEngine = No AttachLaunchAction = No IORedirection = Auto EndProjectSection EndProject
但用MSBuild(本地或TeamCity)构建解决方案时,会输出如下警告:
EXEC : warning : Project file C:\Projects\Transcelerator\%ParatextInstallDir%\Paratext.exe cannot be found. [C:\Projects\Transcelerator\build\Transcelerator.proj]
本地构建时找不到文件的原因是MSBuild会把构建文件夹拼接到路径开头,且不会展开%ParatextInstallDir%环境变量;TeamCity中则既没定义该环境变量,也不存在Paratext.exe文件。命令行构建不需要这个EXE,但希望消除该警告。
想咨询两个方向的解决办法:
- 让解决方案中的这个项目具备条件性(找不到文件则不加载)
- 通过MSBuild命令行参数或配置文件指定抑制该警告
注:我知道可以在MSBuild命令行逐个指定要构建的项目,但这种方式需要在添加或移除常规项目时同步维护,而且无法通过配置控制(该外部项目已不在任何配置中)。
一、让项目条件性加载(仅在文件存在时加载)
Visual Studio的.sln文件本身不支持原生条件判断,但可以通过以下两种方式实现类似效果:
1. 使用MSBuild条件导入(推荐)
把调试启动项目的定义从.sln中移除,转而创建单独的配置文件实现条件加载:
- 创建
DebugLaunchProject.props文件,内容如下:
<Project> <ItemGroup Condition="Exists('$(ParatextInstallDir)\Paratext.exe')"> <ProjectReference Include="$(ParatextInstallDir)\Paratext.exe"> <Project>{64795DCD-9F35-4E20-9A1F-888A6416329A}</Project> <Name>Paratext</Name> </ProjectReference> </ItemGroup> </Project>
- 在插件项目文件(
.csproj/.vcxproj)中导入该props文件:
<Import Project="DebugLaunchProject.props" Condition="Exists('DebugLaunchProject.props')" />
- 从
.sln文件中删除原Paratext项目定义。
MSBuild构建时会自动判断文件是否存在,不存在则不加载该项目,不会触发警告。
2. 手动修改解决方案文件(临时方案)
这种方式依赖命令行语法,VS可能会在修改解决方案时覆盖更改,仅作临时参考:
将.sln中原项目定义替换为:
If Exist "%ParatextInstallDir%\Paratext.exe" ( Project("{911E67C6-3D85-4FCE-B560-20A9C3E3FF48}") = "Paratext", "%ParatextInstallDir%\Paratext.exe", "{64795DCD-9F35-4E20-9A1F-888A6416329A}" ProjectSection(DebuggerProjectSystem) = preProject PortSupplier = 00000000-0000-0000-0000-000000000000 Executable = %ParatextInstallDir%\Paratext.exe RemoteMachine = LSDEV-TBOGLE StartingDirectory = %ParatextInstallDir% Environment = Default LaunchingEngine = fb0d4648-f776-4980-95f8-bb7f36ebc1ee UseLegacyDebugEngines = No LaunchSQLEngine = No AttachLaunchAction = No IORedirection = Auto EndProjectSection EndProject )
注:VS打开解决方案时可能会忽略该判断,仍尝试加载项目。
二、通过MSBuild参数或配置抑制警告
如果不想修改解决方案/项目结构,可直接抑制该警告:
1. 命令行参数方式
在MSBuild命令中添加参数,将EXEC类警告转为消息输出:
msbuild YourSolution.sln /warnasmessage:EXEC
由于该警告无单独编号,只能按类别抑制整个EXEC类警告。
2. 项目配置文件方式
在Transcelerator.proj中添加全局配置,抑制EXEC类警告:
<Project> <!-- 其他现有配置 --> <PropertyGroup> <MSBuildWarningsAsMessages>EXEC</MSBuildWarningsAsMessages> </PropertyGroup> </Project>
内容的提问来源于stack exchange,提问作者Tom Bogle

