user3167162
user3167162

Reputation: 495

MSBuild copy files to directory path with wildcard

I have a DLL that I want to copy to "\Folder1\DestinationDir" and "\Folder2\DestinationDir". I tried using a wild carded destination path:

"\Folder*\DestinationDir", 

but I got an error:

No Destination specified for Copy.

Here's my XML:

<ItemGroup>
  <ItemToCopy Include="$(OutDir)Mydll.dll" />
</ItemGroup>
<ItemGroup>
  <DeployPath Include="$(MSBuildProjectDirectory)\Folder*\DestinationDir" />
</ItemGroup>
<MakeDir Directories="$(DeployPath)" />
<Copy SourceFiles="@(ItemToCopy)" DestinationFolder="%(DeployPath.FullPath)" />

Any help would be much appreciated.

See also

Creating a list of Folders in an ItemGroup using MSBuild

Upvotes: 13

Views: 10728

Answers (1)

George Polevoy
George Polevoy

Reputation: 7681

You build file does not work because ItemToCopy does not expand directory paths, it expands files.

So, if you want to enumerate directories, you should target the existing files in those directoris, then get directory list from the file list.

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemGroup>
        <ItemToCopy Include="$(MSBuildProjectDirectory)\toCopy.txt" />
    </ItemGroup>
    <ItemGroup>
        <DeployPath Include="$(MSBuildProjectDirectory)\Folder*\*.*" />
        <DeployFolders Include="@(DeployPath->'%(RootDir)%(Directory)'->Distinct())" />
    </ItemGroup>
    <Target Name="Test">
        <Copy SourceFiles="@(ItemToCopy)" DestinationFolder="%(DeployFolders.FullPath)" />
        <Message Text="Destination folder = @(DeployFolders)" />
    </Target>
</Project>

Note that this would NOT work for empty directories. Another thread discusses this problem: Creating a list of Folders in an ItemGroup using MSBuild

I would recommend to specify a set of folders explicitly. This can be done with item metadata, for example, and not rely on existing folder structure:

<ItemGroup>
    <DeploySpecificFolders Include="$(MSBuildProjectDirectory)\toCopy.txt">
        <FolderToCopyTo>Folder1</FolderToCopyTo>
    </DeploySpecificFolders>
</ItemGroup>
...
<Message Text="Specific folders = %(DeploySpecificFolders.FullPath) will be copies to %(DeploySpecificFolders.FolderToCopyTo)" />
<Copy SourceFiles="@(DeploySpecificFolders)" DestinationFolder="$(MSBuildProjectDirectory)\%(DeploySpecificFolders.FolderToCopyTo)" /> 

Upvotes: 11

Related Questions