Çıktı Dizinine Kopyala, klasör yapısını kopyalar ancak yalnızca dosyaları kopyalamak ister


87

Bir VS2008'im var Belirli dosyaları bir dizinden /bin/klasörüme kopyalamak istiyorum . Dosyaları (içinde bulunan /common/browserhawk/) "Çıktı Dizinine Kopyala" olarak ayarladım . Bununla birlikte, klasör yapısını da kopyalar: dosyalar,/bin/common/browserhawk/

Bu dosyaların sadece kopyalanmasını nasıl sağlayabilirim /bin/? Doğru şekilde kopyalamalarını sağlamak için bunları web sitesinin kökünde saklamak istemiyorum.

İlgili Soru: Visual Studio, derledikten sonra projeye .dll ve .pdb ekler

Yanıtlar:


59

Dosyaları kopyalamak için bir Oluşturma Sonrası Etkinliği ekleyebilirsiniz.
Proje özelliklerine, Olayları Oluştur sekmesine gidin ve derleme sonrası olay komut satırına aşağıdakileri ekleyin:

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

Proje yolunuzda boşluklar varsa tırnak işaretlerini eklediğinizden emin olun.


Bu tavsiye için teşekkürler, benim için VS2012'de de işe yaradı.
Dib

2
Benim durumumda bunu biraz değiştirdim:xcopy /s /d /y "$(ProjectDir)\stuff" "$(TargetDir)\stuff"
Danny Staple

44

Önceki cevaplara yorum yapamayacağım için çözümü buraya koyacağım:

@PaulAlexander'ın sağladığını ekleyerek, aşağıdakileri .csproj / .vbproj dosyanıza ekleyin:

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

Bu, Özellikler penceresinde Derleme Eylemi olarak "RootContent" i seçmenize olanak tanır ve hepsine GUI aracılığıyla erişilebilir. Daha eksiksiz bir açıklama: "AvailableItemName" seçeneği temelde, projedeki öğeleri Özellikler penceresindeki "Build Action" özelliği altında atayabileceğiniz yeni bir adlandırılmış liste oluşturur. Daha sonra bu yeni oluşturulan listeyi istediğiniz herhangi bir Hedefte kullanabilirsiniz (örn. "@ (RootContent)" aracılığıyla).


Güzel cevap, bunu başarı için kendim kullandım!
Chris Marisic

Ayrıca VS 2010'un (eski sürümlerden emin değilsiniz) AvailableItemNameproje dosyasını VS içinde düzenlerseniz geçersiz bir öğe olduğundan şikayet edeceğini unutmayın; sadece uyarıyı görmezden gelin, yine de çalışır.
Aaronaught

2
Ne yazık ki bu, dosyayı yalnızca dosyanın ait olduğu projenin çıktı dizinine kopyalar - başlangıç ​​projesinin çıktı dizinine değil. Bunu bir kütüphane projesinde kullanırken bu önemlidir.
Sebastian Krysmanski

2
Bu, vs2008 ile sürüm ve hata ayıklama modunda derleme için harika çalışıyor, ancak tek tıklamayla yayınlama kullanılırken çalışmıyor gibi görünüyor. Herhangi bir öneri?
Soenhay

2
2015'e karşı benim için çalışmadı. Hedefin biraz yeniden yazılmasıyla düzeltildi: <Target Name="RootOutputCopyTarget" AfterTargets="Build">... </Target>
lorond

44

.Csproj / .vbproj dosyasını bir metin düzenleyicide düzenlerseniz, dosyanın çıktı dizininde nereye yerleştirileceğini ve ayrıca dosyanın çıktı dizininde hangi ada sahip olacağını kontrol edebilirsiniz. Örneğin:

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

Bu dosyayı content\someContent.txtiçine koyacaktır bin\someContentInOutputDirectory.txt. İsterseniz bir alt dizin de seçebilirsiniz bin; bunu Link öğesine eklemeniz yeterlidir.


3
Vay canına, buna iki gün önce değil, şimdi ihtiyacım olduğu için şanslıydım. Teşekkürler; bu harika!
Asherah

2
Aman tanrım, teşekkürler. VS'nin .dll dosyalarını akıllı bir şekilde kopyalamadığı bazı köşe durum çöplerini düzeltmek için 6 saatimi harcadım. Bu hayata, evrene ve her şeye gerçek cevap.
Brandon

5
Bu açık ara en iyi çözüm
PhilHdt

1
Bunu yaptıktan ve projeyi görsel stüdyoya yeniden yükledikten sonra, bağımlılık dosyalarının projeye dahil edilmemiş gibi çözüm gezgininden kaybolduğunu gördüm. Ancak yine de beklendiği gibi oluşturulur ve istendiği gibi çıktıya kopyalar. Çözüm olarak şu anda her dosyayı iki kez ekliyorum; bir kez eylemsiz ve bir kez 'çıktıya kopyala' ayarlı.
Éliette

1
Bu, bu etiketin amaçlanan kullanımı değildir. VS2013'te bu, proje yüklenirken bir uyarı atar ve dosya proje dizini olduğu için projeye eklendiği gibi görünmez.
jpmc26

15

XCOPY komutunun dizinleri ve dosyaları daha iyi işlediğine inanıyorum. Bu nedenle,

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

Bu, hedef dizinin dışında klasörler oluşturmaya izin verir.

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

Proje klasörü / dosya yapısı:

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

Oluyor:

    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

/Dolası değişikliklerin üzerine yazmaktan kaçınmak için de yararlı olabilir.
KurzedMetal

10

Aşağıdakileri .csproj / .vbproj dosyanıza ekleyin

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

Ardından, kök klasörde olmasını istediğiniz dosyaların Derleme Eylemini RootContent olarak değiştirin.


Diyaloglar aracılığıyla değil ... ama projenizi VS'de düzenleyebilirsiniz. Projeye sağ tıklayın ve Projeyi Kaldır'ı seçin. Ardından sağ tıklayın ve Düzenle'yi seçin. Ardından, projeniz olan MSBuild dosyasını düzenleyebilirsiniz.
Paul Alexander

2
Teşekkürler, bu faydalı görünüyor. Maalesef, snippet'inizi .vbproj dosyasına ekledikten sonra bile RootContent, "Derleme Eylemi" açılır listesinde görünmez ve manuel olarak girildiğinde, Visual Studio "Özellik değeri geçerli değil" hatasıyla sonuçlanır. Ne kaçırdım?
Heinzi

Visual Studio 2010 C # Konsol Uygulaması projesiyle çalışmıyor.
AMissico

Visual Studio 2010 VB.NET Konsol Uygulaması projesi ile çalışmıyor.
AMissico

Visual Studio 2008 C # Konsol Uygulaması projesi ile çalışmıyor.
AMissico

5

Bunu VS2010, VS2015, VS2017 ve VS2019'da kullandım. Bu çözümü tercih ediyorum çünkü:

  1. XML herhangi bir projede yeniden kullanılabilir
  2. "RootContent", diğer "İçerikler" gibi, Visual Studio kullanıcı arayüzünde bir Yapı Eylemi olarak seçilir.
  3. Tıpkı beklediğiniz gibi "CopyToOutputDirectory" yönergesine uyulur
  4. RootContent projenin çıktısına eklenir: Proje Referansları aracılığıyla taşınır, "Temiz" e uyar, vb.
  5. RootContent, özyinelemeli klasör yapısı korunarak bir joker karakterle belirtilebilir:
<RootContent Include="common\browserhawk\**">
  <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</RootContent>

Proje dosyasının başlangıcına doğru:

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

Bu Cevaptan Ödünç Alındı

Microsoft .targets İçe Aktarma işleminden sonra:

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

Bu Cevaptan Ödünç Alındı


Bu iyi - bunun bu projeye eklediğimiz özel içerik olduğunu ve bu şekilde kopyalanması gerektiğini belirtmek RootContentiçin "sabit kodlanmış" anlamına gelen değiştirebilirim CustomContent. Ayrıca bir yana, TargetPath=%(RecursiveDir)%(Filename)%(Extension)klasör yapısını belirtilen CustomContentdosyalardan çıktı yoluna yeniden oluşturmam gerekiyordu .
Jonno

@Jonno Amaç, RecursiveDirectory'den bağımsız olarak dosyaları doğrudan kök çıktı dizinine kopyalamaktır. Yerleşik "İçerik" Derleme Eylemi zaten bize Yinelemeli Dizini korurken kopyalamak için bir mekanizma sağlar.
MattGerg

Bunu bir süredir test etme şansım olmadı, ancak "İçerik" oluşturma eylemini ayarlamak , OP'nin dediği gibi altındaki dosyaların /common/browserhawk/kopyalanmasına neden olmaz /bin/common/browserhawk/mı? IIRC, Niyetim sahip olmaktı /common/browserhawk/a.txtsona /bin/a.txtöyle, ama oraya gelen Özyinelemeyi izin /common/browserhawk/secret/stuff.pngbiter /bin/secret/stuff.png.
Jonno

@Jonno Tamam, evet, bu artık tamamen mantıklı. Yanıtı %(RecursiveDirectory). Bu gerçekten harika, çünkü IDE'de tek tek dosyaları seçmenin yanı sıra, joker karakterlerle birden çok dosya da belirtebilirsiniz. **Joker karakter kullanıldığında, tüm klasör yapısı korunacaktır.
MattGerg

1
Böyle harika cevap için çok teşekkürler! 1. Harici CMDS 2. çapraz platformda: Ben bu yanıt nedeniyle aşağıdakilerden doğru cevaptır düşünüyorum
George Anisimov

2

Başarılı bir derlemeden sonra kopyalamak için nant yapı dosyasına bir adım ekledim

<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 çünkü nant kullanan biri için bu yine de yararlı bir cevap
Chris Haines

1

Dosyaları kopyalamak ve bunu bir derleme sonrası olayı olarak yürütmek için bir toplu iş dosyası oluşturabilirsiniz.


Bunu projelerimden biri için yaptım (yarasa yerine Python betiği kullanmama rağmen).
Fire Lancer
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.