[出力ディレクトリにコピー]はフォルダ構造をコピーしますが、ファイルのみをコピーします


87

特定のファイルをディレクトリから自分の/bin/フォルダーにコピーしたいVS2008があります。ファイル(にあります/common/browserhawk/)を「出力ディレクトリにコピー」に設定しました。ただし、フォルダ構造もコピーされます。ファイルは次の場所にコピーされます。/bin/common/browserhawk/

これらのファイルをコピーする方法を教えてください/bin/。正しくコピーするために、これらをWebサイトのルートに保存したくありません。

関連質問:Visual Studioはコンパイル後にプロジェクトに.dllおよび.pdbを追加します

回答:


59

ビルド後イベントを追加して、ファイルをコピーできます。
プロジェクトのプロパティの[ビルドイベント]タブに移動し、以下をビルド後のイベントコマンドラインに追加します。

copy "$(ProjectDir)\common\browserhawk\*.*" "$(TargetDir)"

プロジェクトパスにスペースが含まれている場合は、必ず引用符を含めてください。


VS2012でも同様に機能するようになりました。
Dib

2
私の場合、これを少し変更しました:xcopy /s /d /y "$(ProjectDir)\stuff" "$(TargetDir)\stuff"
Danny Staple

44

以前の回答にはコメントできないので、ここに解決策を示します。

@PaulAlexanderが提供するものに追加して、以下を.csproj / .vbprojファイルに追加します。

<ItemGroup>
    <AvailableItemName Include="RootContent">
      <Visible>false</Visible>
    </AvailableItemName>  
</ItemGroup>
<Target Name="AfterBuild">
    <Copy
        DestinationFolder="$(OutputPath)"
        SourceFiles="@(RootContent)"
        SkipUnchangedFiles="true"
        />  
</Target>

これにより、[プロパティ]ウィンドウでビルドアクションとして「RootContent」を選択でき、すべてGUIからアクセスできます。より完全な説明:「AvailableItemName」オプションは基本的に、新しい名前付きリストを作成します。この名前付きリストは、プロジェクトの項目を、「プロパティー」ウィンドウの「ビルドアクション」プロパティの下に割り当てることができます。次に、この新しく作成されたリストを任意のターゲットで使用できます(「@(RootContent)経由」など)。


いい答えです、これを自分で使って成功させました!
Chris Marisic、2011年

また、VS 2010(古いバージョンについては不明)はAvailableItemName、VS内でプロジェクトファイルを編集すると、無効な要素であると警告します。警告を無視するだけで、とにかく機能します。
アーロンノート、2011年

2
残念ながら、これは、ファイルが属するプロジェクトの出力ディレクトリにファイルをコピーするだけで、スタートアッププロジェクトの出力ディレクトリにはコピーしません。これは、ライブラリプロジェクトでこれを使用する場合に重要です。
Sebastian Krysmanski 2012

2
これは、vs2008でのリリースモードとデバッグモードでのビルドに最適ですが、ワンクリックパブリッシングを使用すると機能しないようです。助言がありますか?
Soenhay 2013

2
vs2015では私には使えませんでした。ターゲットを少し書き換えることで修正:<Target Name="RootOutputCopyTarget" AfterTargets="Build">... </ Target>
lorond

44

テキストエディタで.csproj / .vbprojを編集する場合、ファイルが出力ディレクトリに配置される場所と、ファイルが出力ディレクトリに付ける名前を制御できます。例えば:

<None Include="content\someContent.txt">
  <Link>someContentInOutputDirectory.txt</Link>
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>

これにより、ファイルがに配置content\someContent.txtされbin\someContentInOutputDirectory.txtます。bin必要に応じて、サブディレクトリを選択することもできます。Link要素に追加するだけです。


3
うわー、これが必要になったのは2日前ではなくて幸運でした。ありがとう。これは素晴らしい!
アシェラ2014

2
ああ、神様、ありがとうございます。私は、VSが.dllをインテリジェントな方法でコピーしていなかったコーナーケースのゴミを修正するために6時間費やしました。これが、生命、宇宙、そしてすべてに対する真の答えです。
ブランドン、2014年

5
これは断然最良の解決策です
PhilHdt '20 / 06/14

1
これを実行してVisual Studioでプロジェクトをリロードすると、依存関係ファイルがプロジェクトに含まれていないかのようにソリューションエクスプローラーから消えました。ただし、期待どおりにビルドされ、必要に応じて出力にコピーされます。回避策として、現在各ファイルを2回追加しています。1回はアクションなしで、もう1回は「出力へのコピー」が設定されます。
Éliette

1
これは、このタグの使用目的ではありません。VS2013では、プロジェクトの読み込み時に警告がスローされ、ファイルはプロジェクトディレクトリであるため、プロジェクトに追加されたものとして表示されません。
jpmc26 2016

15

XCOPYコマンドはディレクトリとファイルをより適切に処理すると思います。したがって、

    XCOPY "$(ProjectDir)common/browserhawk" "$(TargetDir)" /E /I /F /Y

これにより、ターゲットディレクトリからフォルダを作成できます。

    XCOPY "$(ProjectDir)Templates" "$(TargetDir)" /E /I /F /Y

以下のプロジェクトフォルダ/ファイル構造:

    A:\TEMP\CONSOLEAPPLICATION3\TEMPLATES
    ├───NewFolder1
    ├───NewFolder2
    │       TextFile1.txt
    │       TextFile2.txt
    └───NewFolder3
            TextFile1.txt
            TextFile2.txt
            TextFile3.txt

になる:

    A:\TEMP\CONSOLEAPPLICATION3\BIN\DEBUG
    │   ConsoleApplication3.exe
    │   ConsoleApplication3.pdb
    │   ConsoleApplication3.vshost.exe
    │   ConsoleApplication3.vshost.exe.manifest
    ├───NewFolder1
    ├───NewFolder2
    │       TextFile1.txt
    │       TextFile2.txt
    │
    └───NewFolder3
            TextFile1.txt
            TextFile2.txt
            TextFile3.txt

/D可能な変更を上書きしないようにするためにも役立ちます。
KurzedMetal 2015

10

以下を.csproj / .vbprojファイルに追加します

<Target Name="AfterBuild">
    <Copy
        DestinationFolder="$(OutputPath)"
        SourceFiles="@(RootContent)"
        SkipUnchangedFiles="true"
        />  
</Target>

次に、ルートフォルダー内の必要なファイルのビルドアクションをRootContentに変更します。


ダイアログからではなく... VSでプロジェクトを編集できます。プロジェクトを右クリックして、「プロジェクトのアンロード」を選択します。次に、右クリックして「編集」を選択します。次に、プロジェクトであるMSBuildファイルを編集できます。
ポールアレクサンダー

2
おかげで、これは便利に見えます。残念ながら、スニペットを.vbprojファイルに追加した後でもRootContent、「ビルドアクション」ドロップダウンリストに表示されず、手動で入力すると、Visual Studioから「プロパティ値が無効です」というエラーが発生します。私は何を取りこぼしたか?
ハインツィ

Visual Studio 2010 C#コンソールアプリケーションプロジェクトでは機能しません。
AMissico 2010

Visual Studio 2010 VB.NETコンソールアプリケーションプロジェクトでは機能しません。
AMissico

Visual Studio 2008 C#コンソールアプリケーションプロジェクトでは機能しません。
AMissico 2010

5

私はこれをVS2010、VS2015、VS2017、およびVS2019で使用しました。私はこの解決策を好みます:

  1. XMLはどのプロジェクトでも再利用できます
  2. 「RootContent」は、他の「コンテンツ」と同様に、Visual Studio UIでビルドアクションとして選択されます
  3. 「CopyToOutputDirectory」は、あなたが期待するように、従われます
  4. RootContentがプロジェクトの出力に追加されます。Project-Referencesを介して取得され、「Clean」に従います。
  5. RootContentはワイルドカードで指定でき、再帰的なフォルダー構造を維持します。
<RootContent Include="common\browserhawk\**">
  <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</RootContent>

プロジェクトファイルの先頭に向かって:

  <ItemGroup>
    <AvailableItemName Include="RootContent">
      <!-- Add "RootContent" as a choice in the "Build Action" dropdown. -->
      <Visible>True</Visible>
    </AvailableItemName>
  </ItemGroup>

この回答から借りました

Microsoft .targetsインポート後:

  <PropertyGroup>
    <AssignTargetPathsDependsOn>
      $(AssignTargetPathsDependsOn);
      IncludeRootContentAsContent;
    </AssignTargetPathsDependsOn>
  </PropertyGroup>
  <Target Name="IncludeRootContentAsContent">
    <CreateItem Include="@(RootContent)" AdditionalMetadata="TargetPath=%(RecursiveDir)%(Filename)%(Extension)">
      <Output ItemName="ContentWithTargetPath" TaskParameter="Include" />
    </CreateItem>
  </Target>

この回答から借りました


これは良いことです。RootContentつまりCustomContent、このプロジェクトに追加する特別なコンテンツであり、この特定の方法でコピーする必要があることを示すために、「ハードコード」を意味するように交換します。また、余談ですが、TargetPath=%(RecursiveDir)%(Filename)%(Extension)指定したCustomContentファイルから出力パスにフォルダー構造を再作成する必要がありました。
ジョンノ2015

@Jonno目標は、RecursiveDirectoryに関係なく、ファイルをルート出力ディレクトリに直接コピーすることです。組み込みの「コンテンツ」ビルドアクションは、RecursiveDirectoryを維持しながらコピーするメカニズムをすでに提供しています。
MattGerg 2016年

しばらくこれをテストする機会がありませんでしたが、「コンテンツ」ビルドアクションを設定/common/browserhawk/する/bin/common/browserhawk/と、OPが言ったように下のファイルがコピーされませんか?IIRC、私の意図は/common/browserhawk/a.txt最終的にはあるが/bin/a.txt、そこからの再帰を許可することだったので、最終的にはに/common/browserhawk/secret/stuff.pngなりました/bin/secret/stuff.png
ジョンノ2016

@Jonnoわかりました、ええ、それは今完全に理にかなっています。を含めるように回答を更新しました%(RecursiveDirectory)。IDEで個々のファイルを選択するだけでなく、ワイルドカードを使用して複数のファイルを指定することもできるので、これは本当にすばらしいです。**ワイルドカードを使用すると、フォルダー構造全体が保持されます。
MattGerg 2016

1
そのような素晴らしい答えを本当にありがとう!次の理由から、この答えは正しい答えだと思います。1.外部コマンドがない2.クロスプラットフォーム
George Anisimov

2

コンパイルが成功した後にコピーするステップをnantビルドファイルに追加してしまいました

<target name="action.copy.browserhawk.config" depends="compile.source">
    <copy todir="${App.Web.dir}/bin/" includeemptydirs="false">
        <fileset basedir="${browserhawk.config.dir}">
            <include name="bhawk_bb.dat" />
            <include name="bhawk_sp.dat" />
            <include name="browserhawk.properties" />
            <include name="maindefs.bdd" />
            <include name="maindefs.bdf" />
            <include name="BH_PRO.lic" />
        </fileset>
    </copy>
    <echo message="COPY BROWSERHAWK CONFIG: SUCCESS   ${datetime::now()}" />
</target>

2
1 NAntのを使用して誰かのためにこれはまだ役に立つ答えであるので
クリス・ヘインズ

1

バッチファイルをビルドしてファイルをコピーし、ビルド後のイベントとして実行できます。


私は自分のプロジェクトの1つでこれを行うことになりました(バットではなくPythonスクリプトを使用しましたが)。
Fire Lancer
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.