MSBuild Select 部分 RecursiveDir

MSBuild Select partial RecursiveDir

我有一个看起来像这样的项目:

src\ModuleA\code\somepath\test.js
src\ModuleA\code\ignorethis.txt
src\ModuleB\code\awesome.js
src\ModuleB\code\testing\file.js

我想使用像这样的 ItemGroup 从模块中获取所有这些 js 文件:

<ItemGroup>
  <_Scripts Include="..\..\..\src\**\code\**\*.js"/>
</ItemGroup>

但是当我将它们复制到输出中时,我想去除模块和代码路径。如果我使用这样的副本

<Copy SourceFiles="@(_Scripts)" DestinationFiles="@(Scripts->'..\tmp\Test\%(RecursiveDir)%(Filename)%(Extension)')"/>

结果如下所示(因为 RecursiveDir 包含从第一个 ** 开始的整个路径)

tmp\Test\ModuleA\code\somepath\test.js
tmp\Test\ModuleB\code\awesome.js
tmp\Test\ModuleB\code\testing\file.js

但是我试图得到这样的结果:

tmp\Test\somepath\test.js
tmp\Test\awesome.js
tmp\Test\testing\file.js

我尝试过添加带有函数的元数据,但我似乎无法找到使这项工作所需的正确转义。我的最后一次尝试是这样的(如果我可以剥离至少一层文件夹,我假设剥离第二层将是另一个 Meta 元素中的简单重复...)

<Scripts Include="@(_Scripts)">
  <NewDir>$(&quot;%(_Scripts.RecursiveDir)&quot;.Substring(0, &quot;%(_Scripts.RecursiveDir)&quot;.IndexOf(&quot;\&quot;)))</NewDir>
</Scripts>

这会产生 Error MSB4184: The expression <cut for brevity> cannot be evaluated.

如果有更简单的方法或者任何人都可以告诉我正确的转义序列是什么来让它工作?

在努力转义并解析和处理值之后,我设法使用以下方法解决了它:

<_ScriptsFiles Include="..\..\..\src\*\code\**\*.js"/>
<_Scripts Include="@(_ScriptsFiles)">
  <FirstSlash>$([System.String]::new('%(_ScriptsFiles.RecursiveDir)').IndexOf('\'))</FirstSlash>
  <DirMinusOne>$([System.String]::new('%(_ScriptsFiles.RecursiveDir)').Substring(%(_Scripts.FirstSlash)))</DirMinusOne>
  <SecondSlash>$([System.String]::new('%(_Scripts.DirMinusOne)').IndexOf('\', 1))</SecondSlash>
  <DirMinusTwo>$([System.String]::new('%(_Scripts.DirMinusOne)').Substring(%(_Scripts.SecondSlash)))</DirMinusTwo>
</_Scripts>
<Copy SourceFiles="@(_Scripts)" DestinationFiles="@(_Scripts->'..\..\..\tmp\%(DirMinusTwo)\%(Filename)%(Extension)')"/>