Làm thế nào để làm cho Visual Studio sao chép tệp DLL vào thư mục đầu ra?


101

Tôi có một dự án Visual Studio C ++ dựa trên tệp DLL bên ngoài. Làm cách nào để tôi có thể làm cho Visual Studio sao chép tệp DLL này tự động vào thư mục đầu ra (gỡ lỗi / phát hành) khi tôi xây dựng dự án?

Câu trả lời:


90

Sử dụng một hành động sau xây dựng trong dự án của bạn và thêm các lệnh để sao chép DLL vi phạm. Hành động sau xây dựng được viết dưới dạng tập lệnh hàng loạt.

Thư mục đầu ra có thể được tham chiếu như $(OutDir). Thư mục dự án có sẵn dưới dạng $(ProjDir). Cố gắng sử dụng các bản vá tương đối nếu có thể, để bạn có thể sao chép hoặc di chuyển thư mục dự án của mình mà không làm hỏng hành động sau xây dựng.


25
Cũng cần chỉ ra rằng anh ta có thể thiết lập sự kiện sau khi xây dựng thông qua Dự án> Thuộc tính> Sự kiện xây dựng> Sự kiện sau xây dựng.
Phil Booth


36
Trong trường hợp liên kết bị ngắt: "xcopy / y" $ (ProjectDir) *. Dll "" $ (OutDir) "
ace

Tôi đã thay đổi ở trên thành cách cá nhân tôi sử dụng lệnh trong các trường hợp của mình. Điều này sẽ; sao chép các tệp chỉ đọc tốt với quyền kiểm soát nguồn và tạo thư mục đích (thông thường không cần thiết). -> xcopy "$ (ProjectDir) *. dll" "$ (OutDir)" / i / r / y
Ăn tại Joes

8
Thêm cờ / d vào xCopy để ngăn việc sao chép lại không cần thiết các tệp chưa thay đổi trong thư mục đầu ra.
Zoey

43

$ (OutDir) hóa ra là một đường dẫn tương đối trong VS2013, vì vậy tôi phải kết hợp nó với $ (ProjectDir) để đạt được hiệu quả mong muốn:

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

BTW, bạn có thể dễ dàng gỡ lỗi các tập lệnh bằng cách thêm 'echo' vào đầu và quan sát văn bản được mở rộng trong cửa sổ xuất bản dựng.


3
$ (TargetDir) có thể thay thế $ (ProjectDir) $ (OutDir) vì dù sao nó cũng là sự kết hợp của cả hai.
person27

Trong trường hợp của tôi mà không có / d, nó đang xuất hiện lỗi Access Denied. Nhưng / d theo tài liệu là dành cho ngày. Không chắc chắn kết nối là gì.
Ravi C

1
Việc thêm / d ngăn không cho ghi đè nếu tệp nguồn cũ hơn hoặc giống với tệp hiện có. Lỗi bị từ chối truy cập có thể xảy ra nếu mục tiêu bị khóa bởi một quy trình khác.
Rich Shealer

7

Chi tiết trong phần nhận xét ở trên không phù hợp với tôi (VS 2013) khi cố gắng sao chép dll đầu ra từ một dự án C ++ sang thư mục phát hành và gỡ lỗi của dự án C # khác trong cùng một giải pháp.

Tôi đã phải thêm hành động sau khi xây dựng sau (nhấp chuột phải vào dự án có đầu ra .dll) sau đó là thuộc tính -> thuộc tính cấu hình -> xây dựng sự kiện -> sự kiện hậu xây dựng -> dòng lệnh

bây giờ tôi đã thêm hai dòng này để sao chép dll đầu ra vào hai thư mục:

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

5

(Câu trả lời này chỉ áp dụng cho C # không phải C ++, xin lỗi tôi đã đọc nhầm câu hỏi ban đầu)

Tôi đã trải qua địa ngục DLL như thế này trước đây. Giải pháp cuối cùng của tôi là lưu trữ các DLL không được quản lý trong DLL được quản lý dưới dạng tài nguyên nhị phân và giải nén chúng vào một thư mục tạm thời khi chương trình khởi chạy và xóa chúng khi nó được xử lý.

Đây phải là một phần của cơ sở hạ tầng .NET hoặc pinvoke, vì nó rất hữu ích .... Nó giúp DLL được quản lý của bạn dễ dàng quản lý, cả bằng cách sử dụng Xcopy hoặc dưới dạng tham chiếu Dự án trong giải pháp Visual Studio lớn hơn. Khi bạn làm điều này, bạn không phải lo lắng về các sự kiện sau xây dựng.

CẬP NHẬT:

Tôi đã đăng mã ở đây trong một câu trả lời khác https://stackoverflow.com/a/11038376/364818


1
Tôi đồng ý, nó phải là một phần của khuôn khổ (để liên kết tĩnh các dll, v.v.) - Cần lưu ý, lưu trữ dll dưới dạng tài nguyên và sau đó giải nén nó trong thời gian chạy có thể gây ra sự cố trong một số môi trường công ty (đặc biệt nếu chúng có khá phần mềm diệt vi rút chủ động).
BrainSlugs83

1

Thêm COPY nội trang trong tệp 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>

Có một lỗi lâu dài đối với VS, vui lòng sử dụng ProjectDir thay vì SolutionDir
John_J

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

Bạn cũng có thể tham khảo một đường dẫn tương đối, ví dụ tiếp theo sẽ tìm thấy DLL trong một thư mục nằm phía trên thư mục dự án một cấp. Nếu bạn có nhiều dự án sử dụng DLL trong một giải pháp duy nhất, điều này sẽ đặt nguồn DLL trong một khu vực chung có thể truy cập được khi bạn đặt bất kỳ dự án nào trong số chúng làm Dự án Khởi động.

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

Các /ytùy chọn bản sao mà không xác nhận. Các /dkiểm tra tùy chọn để xem nếu một tập tin tồn tại trong các mục tiêu và nếu có thì chỉ bản sao nếu nguồn có một dấu thời gian mới hơn so với mục tiêu.

Tôi thấy rằng trong ít nhất các phiên bản mới hơn của Visual Studio, chẳng hạn như VS2109, $(ProjDir)là không xác định và phải sử dụng $(ProjectDir)thay thế.

Để ra một thư mục đích trong xcopyphải mặc định là thư mục đầu ra. Điều quan trọng là hiểu $(OutDir)một mình lý trí là không hữu ích.

$(OutDir), ít nhất là trong các phiên bản gần đây của Visual Studio, được định nghĩa là một đường dẫn liên quan đến thư mục đầu ra, chẳng hạn như bin/x86/Debug. Chỉ sử dụng nó làm mục tiêu sẽ tạo một tập hợp thư mục mới bắt đầu từ thư mục đầu ra của dự án. Ví dụ: … bin/x86/Debug/bin/x86/Debug.

Kết hợp nó với thư mục dự án sẽ đưa bạn đến nơi thích hợp. Ví dụ: $(ProjectDir)$(OutDir).

Tuy nhiên $(TargetDir)sẽ cung cấp thư mục đầu ra trong một bước.

Danh sách các macro MSBuild của Microsoft cho các phiên bản Visual Studio hiện tại và trước đó

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.