Question

I would like to run a task if any file in an item list is missing. How do I do that?

My current script has a list of "source" files @(MyComFiles) that I translate another list of "destination" files @(MyInteropLibs), using the following task:

<CombinePath BasePath="$(MyPath)\interop" 
             Paths="@(MyComFiles->'%(filename).%(extension)')">
    <Output TaskParameter="CombinedPaths" 
            ItemName="MyInteropLibs" />
</CombinePath>

I want to check if any of the files in @(MyInteropLibs) is missing and run a task that will create them.

Was it helpful?

Solution

I am not very experienced with MSBuild so there may be better solutions than this but you could write a FilesExist task that takes the file list and passes each file to File.Exists returning true if they do exist and false otherwise and thenn react based on the result

Sorry I can't provide code to help out, my knowlege of MSBuild sytax is not strong

OTHER TIPS

If you only need to create the missing files, and not get a list of the files that were missing you can you the touch task, which will create if the files don't exist.

<Touch Files="@(MyInteropLibs)" AlwaysCreate="True" />

If you only want to create the missing files, and avoid changing timestamps of the existing files, then batching can help

<Touch Files="%(MyInteropLibs.FullPath)" AlwaysCreate="True" 
       Condition=" ! Exists(%(MyInteropLibs.FullPath)) "/>

If you want a list of the files created then

<Touch Files="%(MyInteropLibs.FullPath)" AlwaysCreate="True" 
       Condition=" ! Exists(%(MyInteropLibs.FullPath)) ">
    <Output TaskParameter="TouchedFiles" ItemName="CreatedFiles"/>
</Touch>
<Message Text="Created files = @(CreatedFiles)"/>

You can find out pretty easily using Exec.

To test if ALL of a set of files exists: The DOS FOR /D command accepts a semicolon-separated list of files - i.e. a flattened item array.

<!-- All exist -->
<Exec
  Command="for /D %%i in (@(MyFiles)) do if not exist %%i exit 1"
  IgnoreExitCode="true">
  <Output TaskParameter="ExitCode" PropertyName="ExistExitCode"/>
</Exec>

To test if ANY of a set of files exists: The DOS DIR command accepts a semicolon-separated list of files. It sets the %ERRORLEVEL% to 0 if it finds any files in the list, nonzero if it finds none. (This is the simpler case, but it does not address the original question...)

<!-- Any exists -->
<Exec Command="dir /B @(MyFiles)" IgnoreExitCode="true">
  <Output TaskParameter="ExitCode" PropertyName="DirExitCode"/>
</Exec>

Then most likely you will want to define a boolean property based on the output.

EDIT: BTW this is a code smell. Usually when you find yourself wanting to do this, it's an indication that you should set the Outputs property of the target so it will loop over the items.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top