36

Robocopyは、成功すると1を出力します。これは、成功すると0で終了するほとんどのプログラムとは異なります。Visual Studio(およびMSBUILD)は、終了コード1をエラーとして解釈します。

RobocopyをVisualStudioのビルド後およびビルド前のイベントで使用して、その失敗と成功がビルド環境によって正しく識別されるようにするにはどうすればよいですか?

注:これは多かれ少なかれこの投稿の再投稿です。

4

7 に答える 7

29

リクエストごとにこの回答を追加します。Asafのソリューションに基づいており、skrebbelのコメントを追加しています。

次のようにチェックを簡略化できます。

robocopy <opt> <src> <tgt>
if %errorlevel% leq 1 exit 0 else exit %errorlevel%

コメントで親切に述べたように、「1」を調整することをお勧めします。これは、操作でエラーとして処理する内容によって異なります。robocopyによって返される数を組み合わせて構成するビットの意味を見てください。

0×10重大なエラー。Robocopyはファイルをコピーしませんでした。これは、使用上のエラーか、ソースディレクトリまたは宛先ディレクトリに対する不十分なアクセス権限によるエラーのいずれかです。

0×08一部のファイルまたはディレクトリをコピーできませんでした(コピーエラーが発生し、再試行制限を超えました)。これらのエラーをさらに確認してください。

0×04いくつかの不一致のファイルまたはディレクトリが検出されました。出力ログを調べます。おそらくハウスキーピングが必要です。

0×02いくつかの余分なファイルまたはディレクトリが検出されました。出力ログを調べます。いくつかのハウスキーピングが必要になる場合があります。

0×011つ以上のファイルが正常にコピーされました(つまり、新しいファイルが到着しました)。

0×00エラーは発生せず、コピーも行われませんでした。ソースディレクトリツリーと宛先ディレクトリツリーは完全に同期されています。

于 2012-10-31T17:17:21.967 に答える
19

<src>、<tgt>はコピーのソースとターゲットであり、<opt>はrobocopyオプションです。

robocopy <opt> <src> <tgt>
set rce=%errorlevel%
if not %rce%==1 exit %rce% else exit 0

たとえば、プロジェクトターゲットをc:\ tempにコピーする場合、再試行せずに、すべてのサブディレクトリ(空かどうか)を使用して、次を使用します。

robocopy /R:0 /E $(TargetDir) c:\temp
set rce=%errorlevel%
if not %rce%==1 exit %rce% else exit 0
于 2011-03-29T10:07:38.470 に答える
11

終了コード1をチェックするだけでは正しくありません。これは、 8未満の終了コードは誤りではないためです。

8より大きい値は、コピー操作中に少なくとも1つの障害が発生したことを示します。

(明確にするために、8の終了コードもエラーですSeveral files did not copy:)

したがって、適切なコードは次のようになります。

IF %ERRORLEVEL% GEQ 8 exit 1
exit 0
于 2014-10-25T15:58:43.573 に答える
5

構文的には、PreBuildステップ内で直接機能するコマンドごとに1行のバージョンがあります。

(robocopy "$(ProjectDir)..\Dir1" "$(ProjectDir)Dir1" "Match.*" /a+:R) ^& IF %ERRORLEVEL% GEQ 8 exit 1
(robocopy "$(ProjectDir)..\Dir2" "$(ProjectDir)Dir2" "Match.*" /a+:R) ^& IF %ERRORLEVEL% GEQ 8 exit 1
exit 0

参照:

  • GEQ8の@OhadSchneider回答
  • 出口0が最後にある必要がある理由に関するこの回答。
于 2015-11-10T21:44:34.640 に答える
4

MSBuild拡張パックには、ビルドプロセスで使用できるRobocopyタスクが含まれています。
これは、VSのビルド前/ビルド後のイベントの代わりにあなたのための解決策になることができますか?

その場合は、BeforeBuild、 AfterBuildターゲットをオーバーライドし、Robocopyタスクを呼び出すことでVisual Studioビルドプロセスを拡張できます(必要に応じて他のターゲットもオーバーライドできます。リンクされたMSDNページのリストを参照してください)。
プロジェクトのcsproj/vbprojファイルを開いて次のように編集するよりも、MSBuild拡張パックをダウンロードしてインストールする必要があります。

MSBuild拡張パックのRobocopyタスクをインポートするための次のエントリを追加する

<PropertyGroup>
    <TPath>$(MSBuildExtensionsPath32)\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks</TPath>        
</PropertyGroup>
<Import Project="$(TPath)"/>

BeforeBuild、AfterBuildをオーバーライドし、Robocopyタスクを実行します

<Target Name="BeforeBuild">
<Message Text="Beforebuild" />
  <MSBuild.ExtensionPack.FileSystem.RoboCopy Source="C:\temp\robo_src1" Destination="C:\temp\robo_dest1" Files="*.*" Options="/MIR">
      <Output TaskParameter="ExitCode" PropertyName="Exit" />
      <Output TaskParameter="ReturnCode" PropertyName="Return" />
  </MSBuild.ExtensionPack.FileSystem.RoboCopy>
  <Message Text="ExitCode = $(Exit)"/>
  <Message Text="ReturnCode = $(Return)"/>
</Target>
<Target Name="AfterBuild">
  <MSBuild.ExtensionPack.FileSystem.RoboCopy Source="C:\temp\robo_src2" Destination="C:\temp\robo_dest2" Files="*.*" Options="/MIR">
      <Output TaskParameter="ExitCode" PropertyName="Exit" />
      <Output TaskParameter="ReturnCode" PropertyName="Return" />
  </MSBuild.ExtensionPack.FileSystem.RoboCopy>
  <Message Text="ExitCode = $(Exit)"/>
  <Message Text="ReturnCode = $(Return)"/>
</Target>
于 2011-03-29T10:20:47.800 に答える
4

受け入れられた答えは過剰なIMOです。Robocopyにはすでに終了コードが定義され8ているため、通常、以下の値は問題がないことを示していると見なすことができます。

「8より大きい値は、コピー操作中に少なくとも1つの障害が発生したことを示します。」

それで、あなたのコマンドが、ROBOCOPY $(Source) $(Dest) *.*であるとしましょう。これを単に。と呼びます$(RobocopyBinCommand)

Visual Studioで、ビルド前またはビルド後のイベントのドロップダウンをクリックして、<Edit...>

コマンドの下に新しい行を作成し、IF %ERRORLEVEL% LEQ 8 EXIT 0[プロパティ]ウィンドウを配置して適用して閉じます。例:

例

高度な終了コード要件

1ROBOCOPYがまたはを返した場合にのみビルドを通過させたいとしましょう3OR上記のif-checkでは、CMD.exeでサポートされているのような動作を使用して問題を修正することもできません。この制限は複数の方法で回避できますが、これは最も簡潔な方法の1つだと思います。

if %errorlevel% LEQ 3 echo %errorlevel%|findstr "1 3"

ワンライナーの説明

基本的に、1または3のいずれかを探しているエラーレベルをエコーし​​た結果をパイプします。3または1が含まれている値について、または最初の評価で確認されるため、findstr心配する必要はありません。値は3以下です。その評価が合格すると、実際に合格した場合は、エラーレベルをパイプで処理し、エラーレベルをまたはに比較します。いずれかがfindstrによって検出された場合、findstrは0を終了します。それ以外の場合は、終了しません。エラーレベルが3以下でない場合、エラーレベルは変更されず、ビルドタスクはROBOCOPYの使用を通常どおり1終了します。2316findstr13

于 2019-01-03T00:32:15.160 に答える
0

Visual Studioとインラインで呼び出すよりも、robocopyを開始する方がはるかに簡単であることがわかりました。このように、VisualStudioはrobocopyからのリターンコードを気にしません。

start robocopy . ..\latestbuild

私が見ることができた唯一の違いは、robocopyコマンドを実行するためのコマンドプロンプトが表示されたり消えたりすることです。

startの代わりにcallを使用しても、実際にはコマンドプロンプトは開きません。さらに良いことに、robocopyからの出力をVisualStudioの出力ウィンドウにリダイレクトします。

call robocopy . ..\latestbuild

何らかの理由で、このアプローチは、ビルド前のイベントコマンドラインで使用された場合にのみ機能します。

于 2018-04-09T08:44:31.493 に答える