Як змусити Visual Studio скопіювати файл DLL у вихідний каталог?


101

У мене є проект Visual Studio C ++, який спирається на зовнішній файл DLL. Як я можу змусити Visual Studio автоматично копіювати цей файл DLL у вихідний каталог (налагодження / випуск) під час створення проекту?

Відповіді:


91

Використовуйте дію після складання у своєму проекті та додайте команди, щоб скопіювати DLL-файли, що порушують право. Дія після складання записується як пакетний сценарій.

На вихідний каталог можна посилатися як $(OutDir). Каталог проектів доступний як $(ProjDir). Спробуйте використовувати відносні патчі, де це можливо, щоб ви могли скопіювати або перемістити папку проекту, не порушуючи дії після збирання.


26
Варто також зазначити, що він може встановити подію після складання за допомогою Project> Properties> Build Events> Post-build event.
Філ Бут


37
Якщо посилання коли-небудь перерветься: "xcopy / y" $ (ProjectDir) *. Dll "" $ (OutDir) "
ас

Я змінив вище сказане, як я особисто використовую команду в своїх екземплярах. Це буде; копіювати файли лише для читання, що добре контролювати джерела, та створювати цільовий каталог (як правило, не потрібно). -> xcopy "$ (ProjectDir) *. dll" "$ (OutDir)" / i / r / y
Їжте в Joes

8
Додайте прапор / d до xCopy, щоб уникнути зайвої копіювання файлів, які не змінилися у вихідному каталозі.
Зої

44

$ (OutDir) виявився відносним шляхом у VS2013, тому мені довелося поєднувати його з $ (ProjectDir), щоб досягти бажаного ефекту:

xcopy /y /d  "$(ProjectDir)External\*.dll" "$(ProjectDir)$(OutDir)"

До речі, ви можете легко налагоджувати сценарії, додаючи "ехо" на початку та спостерігаючи за розширеним текстом у вікні виводу збірки.


3
$ (TargetDir) може замінити $ (ProjectDir) $ (OutDir), оскільки це все одно поєднання обох.
особа27

У моєму випадку без d / помилки він кидав помилку, заборонену для доступу. Але / d згідно документації на дату. Не впевнений, який зв’язок.
Ravi C

1
Додавання / d запобігає перезапису, якщо вихідний файл старіший або такий, як існуючий файл. Помилка, відхилена в доступі, може виникнути, якщо ціль заблокована іншим процесом.
Багатий Шилер

7

Деталі в розділі коментарів вище для мене не працювали (VS 2013) при спробі скопіювати вихідний dll з одного проекту C ++ у папку випуску та налагодження іншого проекту C # у межах одного рішення.

Я повинен був додати наступну дію після збирання (правою кнопкою миші на проект, який має вихід .dll), а потім властивості -> властивості конфігурації -> події побудови -> подія після складання -> командний рядок

тепер я додав ці два рядки, щоб скопіювати вихідний dll у дві папки:

xcopy /y $(TargetPath) $(SolutionDir)aeiscontroller\bin\Release
xcopy /y $(TargetPath) $(SolutionDir)aeiscontroller\bin\Debug

5

(Ця відповідь стосується лише C #, а не C ++, вибачте, що я неправильно прочитав оригінальне запитання)

Я пережив пекло DLL, як це раніше. Моє остаточне рішення полягало в тому, щоб зберігати керовані DLL в керованій DLL як бінарні ресурси та витягувати їх у тимчасову папку, коли програма запускається та видаляти їх, коли вона видаляється.

Це має бути частиною інфраструктури .NET або pinvoke, оскільки це так корисно .... Це робить керовану DLL просту в управлінні, як за допомогою Xcopy, так і в якості посилання на проект у більшому рішенні Visual Studio. Після цього вам не доведеться турбуватися про події після збирання.

ОНОВЛЕННЯ:

Я розмістив тут код в іншій відповіді https://stackoverflow.com/a/11038376/364818


1
Я погоджуюся, це має бути частиною основи (статично зв'язувати dll тощо). Варто зазначити, що зберігання dll як ресурсу та потім його витяг під час виконання може спричинити проблеми в деяких корпоративних середовищах (особливо, якщо вони мають досить проактивне антивірусне програмне забезпечення).
BrainSlugs83

1

Додати вбудований COPY у файл project.csproj :

  <Project>
    ...
    <Target Name="AfterBuild">
      <Copy SourceFiles="$(ProjectDir)..\..\Lib\*.dll" DestinationFolder="$(OutDir)Debug\bin" SkipUnchangedFiles="false" />
      <Copy SourceFiles="$(ProjectDir)..\..\Lib\*.dll" DestinationFolder="$(OutDir)Release\bin" SkipUnchangedFiles="false" />
    </Target>
  </Project>

Існує довгострокова помилка VS, скористайтеся ProjectDir, а не SolutionDir
John_J

0
xcopy /y /d  "$(ProjectDir)External\*.dll" "$(TargetDir)"

Ви також можете посилатися на відносний шлях, наступний приклад знайде DLL у папці, розташованій на одному рівні над папкою проекту. Якщо у вас є кілька проектів, які використовують DLL в одному рішенні, це ставить джерело DLL в загальну область, доступну, коли ви встановлюєте будь-який з них як проект запуску.

xcopy /y /d  "$(ProjectDir)..\External\*.dll" "$(TargetDir)"

У /yопціонні копії без підтвердження. У /dперевіряєте опції , щоб побачити , якщо файл існує в цільовому і якщо він робить тільки копію , якщо джерело має новішу тимчасову мітку , ніж мета.

Я виявив, що принаймні новіші версії Visual Studio, як-от VS2109, $(ProjDir)не визначені і повинні $(ProjectDir)замість цього використовувати .

Якщо залишити цільову папку в, xcopyслід за замовчуванням мати вихідний каталог Це важливо, щоб зрозуміти $(OutDir)лише причину не корисно.

$(OutDir), принаймні, в останніх версіях Visual Studio визначається як відносний шлях до папки виводу, наприклад bin/x86/Debug. Використовуючи її як ціль, ви створите новий набір папок, починаючи з вихідної папки проекту. Приклад: … bin/x86/Debug/bin/x86/Debug.

Поєднавши його з папкою проекту, ви повинні перейти до потрібного місця. Приклад: $(ProjectDir)$(OutDir).

Однак $(TargetDir)забезпечить вихідний каталог за один крок.

Список макросів MSBuild від Microsoft для поточної та попередньої версій Visual Studio

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