why does my post-build xcopy always copy the previ

2019-08-16 04:57发布

问题:

I have a solution which creates DLLs and a post-build xcopy that copies them to a target folder where another solution consumes them. I have noticed that all seems to be well but in fact the xcopy always copies the previous version instead of the freshly built one. This is Case A.

Even weirder (but possibly related): when I switched to a batch file to do the xcopy the build hangs. (B) And, finally, if I use a simple copy command in the batch file the build is successful, but again, the wrong version gets copied. (C)

Here are the pieces of the puzzle:

Case A directly in the post-build:

xcopy "$(ProjectDir)bin\Debug\PIC_TextBrowser.dll" "$(SolutionDir)..\ToolBox\ToolBox\bin\Debug\" /Y /I

Case B, a batchfile xcopy.bat call ed from the post-build:

xcopy "PIC_TextBrowser.dll" "D:\P\C#13\ToolBox\ToolBox\ToolBox\bin\Debug\" /Y /I

Case C, a batchfile xcopy.bat call ed from the post-build:

copy "PIC_TextBrowser.dll" "D:\P\C#13\ToolBox\ToolBox\ToolBox\bin\Debug\" /Y 

The targets in the .csproj file look like this:

  <Target Name="BuildPlugins">
    <CSC Sources="PI_base.cs;PIC_TextBrowser.cs" TargetType="library" OutputAssembly="$(OutputPath)PIC_TextBrowser.dll" EmitDebugInformation="true" />
  </Target>
  <Target Name="AfterBuild" DependsOnTargets="BuildPlugins">
  </Target>
  <PropertyGroup>
    <PostBuildEvent>call xcopy.bat
</PostBuildEvent>

Looks like the post-build event is not quite as 'post' as I thought. Any ideas, other than to live with it??

回答1:

It's a bug in VS Express 2012 and 2013. (see Edit below)

OK, you don't believe it and neither do I, so we're all in good company..

But how else can you explain these findings:

I have written two tiny tools to extract the extract time to milliseconds from the files that are built and also from the time the 'postbuild' event starts and ends. This was necessary, as this weirdness happens below the seconds level.

The tools are basically one liners, a console appliction (timeMS) to be used in the batch file, that simply does:

    Console.WriteLine(DateTime.Now.ToString("HH:mm:ss:fff"));

and a winforms program that for each file dropped onto it does:

tb_fileData.Text += file +  "\t" +   
   File.GetLastWriteTime(file).ToString("HH:mm:ss:fff") + "\r\n";

Not a lot of room for errors so far. (OK, one of the famous last words, I grant..)

Then I modified the batch file that gets called in the post-build like this:

echo post-build starts > time.txt
timeMS.exe >> time.txt
xcopy "PIC_Clock.dll" "D:\P\C#13\ToolBox\ToolBox\ToolBox\bin\Debug\" /Y /I
echo post-build ends  >> time.txt
timeMS.exe >> time.txt

And here are the results:

D:\P\C#13\ToolBox\PIClasses\PIClasses\bin\Debug\PIC_Clock.dll   17:25:56:132
D:\P\C#13\ToolBox\ToolBox\ToolBox\bin\Debug\PIC_Clock.dll       17:21:30:778

post-build starts 
17:25:55:929
post-build ends  
17:25:55:960

The first file is the new build, which is not done/released to the file system before the copying is done; so of course, the xcopy always copies the old version, which is the one in the second line, built a few minutes earlier..

Again, I tested this about a dozen times, with both settings: 'After sucessful build' and 'When build refreshes the project output' (or whatever the English version calls it..)

So either it's a bug or a feature, but in any case I don't think I quite understand..

EDIT

OK, probably not really a bug; here is what helped me out: the csproj file offers more possibilties than the options in the property page for build events. Here you can change the Target Name= from "AfterBuild" to "AfterCompile" and lo and behold, now the new version gets copied. Hm, am I alone with all this???

This is how the csproj looks now:

  <Target Name="BuildPlugins">
    <CSC Sources="PIC_Clock.cs" TargetType="library" OutputAssembly="$(OutputPath)PIC_Clock.dll" EmitDebugInformation="true" />
  </Target>
  <Target Name="AfterCompile" DependsOnTargets="BuildPlugins">
  </Target>
  <PropertyGroup>
    <PostBuildEvent>x_copy.bat
</PostBuildEvent>


回答2:

Try Robocopy.exe source dest /S /Z /Log:LogFileName It should at least give you an idea of where you might having a problem.