Копіювати до каталогу вихідних даних копіює структуру папок, але потрібно лише копіювати файли


87

У мене є VS2008, я хочу скопіювати певні файли з каталогу у свою /bin/папку. Я встановив для файлів (що знаходяться в /common/browserhawk/) значення "Копіювати у вихідний каталог". Однак він також копіює структуру папок: файли копіюються в/bin/common/browserhawk/

Як отримати ці файли для копіювання /bin/? Я не хочу зберігати їх у кореневій частині веб-сайту, щоб змусити їх правильно копіювати.

Пов’язане запитання: Visual Studio додає .dll та .pdb до проекту після компіляції

Відповіді:


59

Ви можете додати Подію побудови події, щоб скопіювати файли.
Перейдіть до властивостей проекту, на вкладці "Події збірки" та додайте до командного рядка "Подія після збірки":

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

Не забудьте включити лапки, якщо у вашому шляху до проекту є пробіли.


Дякую за цю пораду, оскільки вона щойно працювала для мене також у VS2012.
Dib

2
Я трохи змінив це у своєму випадку:xcopy /s /d /y "$(ProjectDir)\stuff" "$(TargetDir)\stuff"
Денні Степл

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" як Дію побудови у вікні Властивості, і всі вони можуть бути доступні через графічний інтерфейс. Більш повне пояснення: параметр "AvailableItemName" в основному створює новий іменований список, якому ви можете призначити елементи у проекті під властивістю "Дія побудови" у вікні Властивості. Потім ви можете використовувати цей нещодавно створений список у будь-якій вподобаній цілі (наприклад, за допомогою "@ (RootContent)").


Приємна відповідь, я просто використав це для успіху!
Chris Marisic

Також зауважте, що VS 2010 (не впевнений у старих версіях) скаржиться на AvailableItemNameте, що є недійсним елементом, якщо ви редагуєте файл проекту у VS; просто ігноруйте попередження, воно все одно працює.
Aaronaught

2
На жаль, це копіює файл лише у вихідний каталог проекту, до якого він належить, а не у вихідний каталог запуску проекту. Це важливо при використанні цього в бібліотечному проекті.
Себастьян Крисманскі,

2
Це чудово працює для створення в режимі випуску та налагодження з vs2008, але, здається, це не працює при використанні публікації одним клацанням миші. Будь-які пропозиції?
Soenhay,

2
Не працював у мене в vs2015. Виправлено <Target Name="RootOutputCopyTarget" AfterTargets="Build">
незначним

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
Боже мій, дякую тобі. Я просто витратив 6 годин, намагаючись виправити кут сміття, де VS не інтелектуально копіював .dll. Це справжня відповідь на життя, Всесвіт і все.
Брендон

5
Це, безумовно, найкраще рішення
PhilHdt

1
Як тільки я це зробив і перезавантажив проект у Visual Studio, я виявив, що файли залежностей зникли з провідника рішень, як ніби не включені в проект. Однак він все ще будує, як очікувалося, і копіює на вихід за бажанням. В якості опрацювання я зараз додаю кожен файл двічі; один раз без дії, а один раз із набором "копіювати на вихід".
Елієт,

1
Це не передбачуване використання цього тегу. У VS2013 це видає попередження під час завантаження проекту, і файл не видно, як доданий до проекту, оскільки це каталог проекту.
jpmc26

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

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

Не працює з проектом програми консолі Visual Studio 2010 VB.NET.
AMissico

Не працює з проектом програми консолі Visual Studio 2008 C #.
AMissico

5

Я використовував це у VS2010, VS2015, VS2017 та VS2019. Я віддаю перевагу цьому рішенню, оскільки:

  1. XML багаторазово використовується в будь-якому проекті
  2. "RootContent" вибирається як дія побудови в інтерфейсі Visual Studio, як і будь-який інший "Вміст"
  3. "CopyToOutputDirectory" дотримується, як і слід було очікувати
  4. RootContent додається до результатів проекту: переноситься через посилання на проект, підпорядковується "Очистити" тощо.
  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файлів до вихідного шляху.
Джонно,

@Jonno Мета - скопіювати файли безпосередньо в кореневий каталог виводу, незалежно від RecursiveDirectory. Вбудована дія збірки "Вміст" вже надає нам механізм копіювання, зберігаючи RecursiveDirectory.
MattGerg

Я давно не мав можливості перевірити це, але чи не встановивши дію збірки "Вміст", файли /common/browserhawk/буде скопійовано, /bin/common/browserhawk/як сказано в ОП? IIRC, я мав намір /common/browserhawk/a.txtопинитися в, /bin/a.txtале дозволити рекурсію звідти вниз, тому /common/browserhawk/secret/stuff.pngзакінчується в /bin/secret/stuff.png.
Джонно,

@Jonno Добре, так, зараз це цілком логічно. Я оновив відповідь, включивши %(RecursiveDirectory). Це справді круто, адже крім вибору окремих файлів в IDE, ви також можете вказати кілька файлів із символами підстановки. При використанні **шаблону буде збережена вся структура папок.
MattGerg

1
Велике спасибі за таку чудову відповідь! Я думаю, що ця відповідь є правильною через наступне: 1. Немає зовнішніх cmds 2. крос-платформа
Георгій Анісімов

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, це все одно корисна відповідь
Кріс Хейнс 02

1

Ви можете створити пакетний файл, щоб скопіювати файли та виконати його як подію після збірки.


У підсумку я зробив це для одного зі своїх проектів (хоча я використовував сценарій Python, а не биту).
Fire Lancer
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.