У меня есть сценарий, который пытается построить ItemGroup
из всех файлов в определенном каталоге, исключая файлы с определенными именами (независимо от расширения).MSBuild: звездочки и странные ItemGroup Исключить поведение
Список файлов, которые будут исключены изначально, содержит расширения файлов, и я использую «Задачи сообщества» RegexReplace
, чтобы заменить расширения звездочкой. Затем я использую этот список в атрибуте Exclude
элемента. По какой-то причине файлы не исключаются должным образом, хотя список кажется правильным.
Чтобы попытаться найти причину, я создал тестовый скрипт (ниже), который имеет две задачи: сначала инициализирует два свойства со списком шаблонов файлов в двумя разными способами:. Вторая задача печатает как свойства, так и файлы, полученные в результате использования обоих этих свойств в атрибуте Exclude
.
Значения свойств оказываются идентичными, однако результирующие группы отличаются. Как это возможно?
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
DefaultTargets="Init;Test" ToolsVersion="3.5">
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
<Target Name="Init">
<ItemGroup>
<OriginalFilenames Include="TestDir\SampleProj.exe"/>
<OriginalFilenames Include="TestDir\SampleLib1.dll"/>
</ItemGroup>
<RegexReplace Input="@(OriginalFilenames)" Expression="\.\w+$" Replacement=".*">
<Output TaskParameter="Output" ItemName="PatternedFilenames"/>
</RegexReplace>
<PropertyGroup>
<ExcludeFilesA>TestDir\SampleProj.*;TestDir\SampleLib1.*</ExcludeFilesA>
<ExcludeFilesB>@(PatternedFilenames)</ExcludeFilesB>
</PropertyGroup>
</Target>
<Target Name="Test">
<Message Text='ExcludeFilesA: $(ExcludeFilesA)' />
<Message Text='ExcludeFilesB: $(ExcludeFilesB)' />
<ItemGroup>
<AllFiles Include="TestDir\**"/>
<RemainingFilesA Include="TestDir\**" Exclude="$(ExcludeFilesA)"/>
<RemainingFilesB Include="TestDir\**" Exclude="$(ExcludeFilesB)"/>
</ItemGroup>
<Message Text="
**AllFiles**
@(AllFiles, '
')" />
<Message Text="
**PatternedFilenames**
@(PatternedFilenames, '
')" />
<Message Text="
**RemainingFilesA**
@(RemainingFilesA, '
')" />
<Message Text="
**RemainingFilesB**
@(RemainingFilesB, '
')" />
</Target>
</Project>
Выход (переформатирован немного для ясности):
ExcludeFilesA: TestDir\SampleProj.*;TestDir\SampleLib1.*
ExcludeFilesB: TestDir\SampleProj.*;TestDir\SampleLib1.*
AllFiles:
TestDir\SampleLib1.dll
TestDir\SampleLib1.pdb
TestDir\SampleLib2.dll
TestDir\SampleLib2.pdb
TestDir\SampleProj.exe
TestDir\SampleProj.pdb
PatternedFilenames:
TestDir\SampleProj.*
TestDir\SampleLib1.*
RemainingFilesA:
TestDir\SampleLib2.dll
TestDir\SampleLib2.pdb
RemainingFilesB:
TestDir\SampleLib1.dll
TestDir\SampleLib1.pdb
TestDir\SampleLib2.dll
TestDir\SampleLib2.pdb
TestDir\SampleProj.exe
TestDir\SampleProj.pdb
Заметим, что оба ExcludeFilesA
и ExcludeFilesB
выглядят одинаково, но в результате группы RemainingFilesA
и RemainingFilesB
различаются.
В конечном счете, я хочу получить список RemainingFilesA
, используя шаблон, сгенерированный таким же образом ExcludeFilesB
. Можете ли вы предложить способ, или мне нужно полностью переосмыслить мой подход?
Отличный улов ... хороший! – KMoraz
Большое спасибо! Я попытался фактически избежать звездочки в ' ', чтобы позже получить его дословно без файлового глоблирования, и я не смог найти никакой информации об этом. Ваше исследование помогло мне - использование '% 2a' отключилось, а все' @ -> 'преобразования в более поздней команде получили звездочку. –
quetzalcoatl
aand сразу после написания этого комментария, я нашел https://docs.microsoft.com/en-us/visualstudio/msbuild/special-characters-to-escape, где явно указано для Include и asterisk, d'oh. – quetzalcoatl