I currently create my first MSBuild-script.
I've a tag "Folders" that findes all Directories in a given root path:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<Target Name="Build">
<PropertyGroup>
<RootFolder>tmp</RootFolder>
</PropertyGroup>
<ItemGroup>
<Folders Include="$([System.IO.Directory]::GetDirectories("$(RootFolder)"))"/>
</ItemGroup>
<Message Text="@(Folders -> '%(FullPath)\Bin\Debug\%(Filename)%(Extension).dll', ';')"/>
</Target>
</Project>
That works perfect. My problem is that I only need directories where the specified file exists. I tried a condition like that
Condition="$([System.IO.File]::Exists("%(FullPath)\\Bin\\Debug\\%(Filename)%(Extension).dll"))"
for the folder tag.
This script runs without any error but my list is empty. Why?
Are there any other solutions to check for a file?
I used this solution because it uses C# and I'm a C#-developer.
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<Target Name="Build">
<PropertyGroup>
<RootFolders>tmp</RootFolders>
</PropertyGroup>
<GetFiles rootFolders="$(RootFolders)">
<Output PropertyName="Files" TaskParameter="Files" />
</GetFiles>
<Message Text="$(Files)" />
</Target>
<UsingTask
TaskName="GetFiles"
TaskFactory="CodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup>
<rootFolders ParameterType="System.String" Required="true" />
<files ParameterType="System.String" Output="true" />
</ParameterGroup>
<Task>
<Using Namespace="System" />
<Using Namespace="System.IO" />
<Using Namespace="System.Linq" />
<Code Type="Fragment" Language="cs">
<![CDATA[
Func<string, string> BuildFilePath = path => path + @"\Bin\Debug\" + Path.GetFileName(path) + ".dll";
var dirs = Directory.GetDirectories(rootFolders).Where(x => File.Exists(BuildFilePath(x)));
files = string.Join("\n", dirs.Select(BuildFilePath));
]]>
</Code>
</Task>
</UsingTask>
</Project>
AFAIK, the thing is
Condition
is executed and checked for the whole declaration of Items (i.e.<Folders ..>
tag).I think, you need to loop through the collection (e.g. using target/task batching) and check the file to exist in every single folder folder in the collection. Then if the file exists - include it in the new
<FoldersFiletered>
items collection.NB: I don't have time to test the code now, but this is the idea roughly: