Recursively copy all files with MSBuild

2019-07-07 03:26发布

问题:

I have the following set of files with MSBuild:

<ScriptFiles Include="Server/scripts/**/*.js" />

I then copy all of it over to another directory:

<Copy SourceFiles="@(ScriptFiles)" DestinationFiles="@(ScriptFiles->'$(BuildDir)/WWW/scripts/%(RecursiveDir)%(Filename)%(Extension)')" />

However, what I want to do is copy *.js, and copy /yui/*.*. What I tried doing is:

<ScriptFiles Include="Server/scripts/**/*.js;Server/scripts/yui/**/*" />

However, what this does is flatten the /yui/ directory and put all of yui's files directly into /WWW/scripts.

Is there a better way to do this?

BTW, I'm actually using XBuild and not MSBuild, but from what I've seen the two are for the most part compatible.

回答1:

Updated Ritch's comment (I added Exclude to avoid copying the same files twice):

Shouldn't that be two separate lines:

<ScriptFiles Include="Server/scripts/**/*.js" Exclude="Server/scripts/yui/**/*"/> 
<YuiFiles Include="Server/scripts/yui/**/*" />

OR

<YuiFiles Include="Server/scripts/yui/**/*" />
<ScriptFiles Include="Server/scripts/**/*.js" Exclude="@(YuiFiles)"/> 

<Copy SourceFiles="@(YuiFiles)" DestinationFiles="..." />    
<Copy SourceFiles="@(ScriptFiles)" DestinationFiles="..." />


回答2:

%(RecursiveDir) would match the wildcard part. So, if under /yui/ you had :

yui/foo/bar/abc.dll

Then, yui/**/* would give %(RecursiveDir) as "foo/bar". Is that what you are expecting? If it is, then this should work with xbuild. Which version are you using? (xbuild --help).

"**" is used when you want to collect files from subdirectories also. If what you are trying to do is different, then could you please given an example with few files?

Try something like this:

<Message Text="ScriptFile: %(ScriptFile.Identity) , RD: %(ScriptFile.RecursiveDir)"/>
<Message Text="Paths: @(ScriptFiles->'$(BuildDir)/WWW/scripts/%(RecursiveDir)%(Filename)%(Extension)')"/>

This should give insight into why it is not working.