后台:我管理的是一个相当大的解决方案。每隔一段时间,人们就会在解决方案中为项目添加DLL引用,他们应该添加项目引用。我想在这种情况下发出警告。我想通过在他们的HintPath *中找到'bin \ debug'的所有引用来做到这一点。我知道引用是ItemGroup中的项目,元数据为“HintPath”。
我期待这样的事情发挥作用:
<Warning Text="Reference %(Reference.Identity) should be a project reference. HintPath: %(Reference.HintPath)"
Condition="%(Reference.HintPath).IndexOf('bin\debug') != -1"/>
然而,似乎我不能像这样使用字符串函数IndexOf。我尝试了上述的许多排列,没有成功。
答案 0 :(得分:20)
使用MSBuild 4.0 Property Functions可以进行字符串比较:
<Target Name="AfterBuild">
<Message Text="Checking reference... '%(Reference.HintPath)'" Importance="high" />
<Warning Text="Reference %(Reference.Identity) should be a project reference. HintPath: %(Reference.HintPath)"
Condition="$([System.String]::new('%(Reference.HintPath)').Contains('\bin\$(Configuration)'))" />
</Target>
答案 1 :(得分:2)
首先不是你的语法对于调用函数是不正确的,它需要是:
%(Reference.HintPath.IndexOf(...)) # Note: not supported by MSBuild
但是,MSBuild中的属性函数对项目元数据是not allowed,因此也无法帮助您。
你可以通过调用一个基本上为每个项目调用的单独目标来解决这个问题。
<Target Name="CheckProjectReferences">
<MSBuild
Projects="$(MSBuildProjectFullPath)"
Properties="Identity=%(Reference.Identity);HintPath=%(Reference.HintPath)"
Targets="_Warn"/>
</Target>
<Target Name="_Warn">
<Warning Text="Reference $(Identity) should be a project reference. HintPath: $(HintPath)"
Condition="$(HintPath.IndexOf('bin\debug')) != -1"/>
</Target>
坦率地说,我不确定这是否足以捕获所有“违规行为”。例如,上述内容仅适用于bin\debug
,但不适用于bin\Debug
或其他功能相同的混合外壳变体。要查找它们,您需要调用IndexOf(string, StringComparison)
重载,但只需执行:
$(HintPath.IndexOf('bin\debug', System.StringComparison.OrdinalIgnoreCase))
无法正常工作,因为MSBuild重载决策会选择IndexOf(char, Int32)
并给您出错:
MSB4184:无法计算表达式“”bin \ debug“.IndexOf(bin \ debug,System.StringComparison.OrdinalIgnoreCase)”。字符串必须只有一个字符长。
因此,您需要直接使用IndexOf(String, Int32, Int32, StringComparison)
重载来说服它:
$(HintPath.IndexOf('bin\debug', 0, 9, System.StringComparison.OrdinalIgnoreCase))
您可能还需要检查bin\Release
或其他变体。我不确定这是否是找出引用应该是项目引用的最佳方法,但如果您知道(并且在某种程度上控制)您的环境,那么它可能是可行的。
答案 2 :(得分:0)
@Christian.K在他的分析中是正确的。另一个解决方案是使用"
强制类型字符串的重载用于引号:
<Warning
Text="..."
Condition="$(HintPath.IndexOf("bin\debug", System.StringComparison.OrdinalIgnoreCase)) != -1" />