Jak sprawić, by program Visual Studio skopiował plik DLL do katalogu wyjściowego?

101

Mam projekt Visual Studio C ++, który opiera się na zewnętrznym pliku DLL. Jak mogę sprawić, aby program Visual Studio automatycznie skopiował ten plik DLL do katalogu wyjściowego (debugowanie / wydanie) podczas kompilowania projektu?

Mata
źródło

Odpowiedzi:

91

Użyj akcji po kompilacji w swoim projekcie i dodaj polecenia, aby skopiować naruszającą bibliotekę DLL. Czynności po kompilacji są zapisywane jako skrypt wsadowy.

Do katalogu wyjściowego można się odwoływać jako $(OutDir). Katalog projektu jest dostępny jako $(ProjDir). W stosownych przypadkach spróbuj użyć względnych ścieżek, aby można było skopiować lub przenieść folder projektu bez przerywania czynności po kompilacji.

Adrien Plisson
źródło
26
Warto również zaznaczyć, że może on ustawić zdarzenie post-build poprzez Projekt> Właściwości> Zdarzenia kompilacji> Zdarzenie po kompilacji.
Phil Booth
21
przykład: eyeung003.blogspot.com/2009/11/…
AntonioR
37
W przypadku zerwania łącza: "xcopy / y" $ (ProjectDir) *. Dll "" $ (OutDir) "
as
Zmieniłem powyższe na sposób, w jaki osobiście używam polecenia w moich wystąpieniach. To będzie; kopiuje pliki tylko do odczytu, które są dobre z kontrolą źródła i tworzy katalog docelowy (zwykle nie jest potrzebny). -> xcopy "$ (ProjectDir) *. dll" "$ (OutDir)" / i / r / r
Eat at Joes
8
Dodaj flagę / d do xCopy, aby zapobiec niepotrzebnemu kopiowaniu plików, które nie uległy zmianie w katalogu wyjściowym.
Zoey
44

$ (OutDir) okazał się ścieżką względną w VS2013, więc musiałem połączyć to z $ (ProjectDir), aby osiągnąć zamierzony efekt:

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

Przy okazji, możesz łatwo debugować skrypty, dodając „echo” na początku i obserwując rozszerzony tekst w oknie wyników kompilacji.

Nesho Neshev
źródło
3
$ (TargetDir) może zastąpić $ (ProjectDir) $ (OutDir), ponieważ i tak jest to kombinacja obu.
osoba 27
W moim przypadku bez / d wyrzucał błąd odmowy dostępu. Ale / d zgodnie z dokumentacją dotyczy daty. Nie wiem, jakie jest połączenie.
Ravi C
1
Dodanie / d zapobiega nadpisywaniu, jeśli plik źródłowy jest starszy lub taki sam jak istniejący plik. Błąd odmowy dostępu może wystąpić, jeśli cel jest zablokowany przez inny proces.
Rich Shealer
7

Szczegóły w sekcji komentarzy powyżej nie działały dla mnie (VS 2013) podczas próby skopiowania wyjściowej biblioteki DLL z jednego projektu C ++ do folderu wydania i debugowania innego projektu C # w ramach tego samego rozwiązania.

Musiałem dodać następującą akcję po kompilacji (kliknij prawym przyciskiem myszy projekt, który ma dane wyjściowe .dll), a następnie właściwości -> właściwości konfiguracji -> zdarzenia kompilacji -> zdarzenie po kompilacji -> wiersz poleceń

teraz dodałem te dwie linie, aby skopiować wyjściową bibliotekę dll do dwóch folderów:

xcopy /y $(TargetPath) $(SolutionDir)aeiscontroller\bin\Release
xcopy /y $(TargetPath) $(SolutionDir)aeiscontroller\bin\Debug
SCBuergel.eth
źródło
5

(Ta odpowiedź dotyczy tylko C #, a nie C ++, przepraszam, że źle przeczytałem oryginalne pytanie)

Przeszedłem już przez piekło DLL w ten sposób. Ostatnim rozwiązaniem było przechowywanie niezarządzanych bibliotek DLL w zarządzanej bibliotece DLL jako zasoby binarne i wyodrębnianie ich do folderu tymczasowego podczas uruchamiania programu i usuwanie ich po usunięciu.

To powinno być częścią .NET lub infrastruktury pinvoke, ponieważ jest tak przydatne .... To sprawia, że udało DLL łatwe do zarządzania, zarówno przy użyciu XCopy lub jako odniesienie projektu w większym rozwiązania Visual Studio. Gdy to zrobisz, nie musisz się martwić wydarzeniami po kompilacji.

AKTUALIZACJA:

Umieściłem kod tutaj w innej odpowiedzi https://stackoverflow.com/a/11038376/364818

Mark Lakata
źródło
1
Zgadzam się, powinno to być częścią frameworka (do statycznego łączenia bibliotek dll itp.) - Warto zauważyć, że przechowywanie biblioteki DLL jako zasobu, a następnie wyodrębnianie jej w czasie wykonywania może powodować problemy w niektórych środowiskach korporacyjnych (zwłaszcza jeśli mają one dość proaktywne oprogramowanie antywirusowe).
BrainSlugs83
1

Dodaj wbudowaną COPY w pliku 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>
John_J
źródło
VS ma długoterminowy błąd, użyj ProjectDir zamiast SolutionDir
John_J
0
xcopy /y /d  "$(ProjectDir)External\*.dll" "$(TargetDir)"

Możesz również odwołać się do ścieżki względnej, następny przykład znajdzie bibliotekę DLL w folderze znajdującym się jeden poziom nad folderem projektu. Jeśli masz wiele projektów korzystających z biblioteki DLL w jednym rozwiązaniu, spowoduje to umieszczenie źródła biblioteki DLL we wspólnym obszarze osiągalnym po ustawieniu dowolnego z nich jako projektu startowego.

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

Te /ykopie opcja bez potwierdzenia. Te /dkontrole opcja aby sprawdzić, czy plik istnieje w docelowej, a jeśli to robi tylko kopie, czy źródło ma nowszą znacznik czasu niż cel.

Odkryłem, że w co najmniej nowszych wersjach Visual Studio, takich jak VS2109, $(ProjDir)jest niezdefiniowany i musiałem go $(ProjectDir)zamiast tego użyć .

Opuszczenie folderu docelowego w xcopypowinno domyślnie przejść do katalogu wyjściowego. Ważne jest, aby zrozumieć, że $(OutDir)sam rozum nie jest pomocny.

$(OutDir), przynajmniej w najnowszych wersjach programu Visual Studio, jest definiowana jako ścieżka względna do folderu wyjściowego, na przykład bin/x86/Debug. Użycie go samodzielnie jako celu spowoduje utworzenie nowego zestawu folderów, zaczynając od folderu wyjściowego projektu. Np … bin/x86/Debug/bin/x86/Debug. : .

Połączenie go z folderem projektu powinno przenieść Cię we właściwe miejsce. Np $(ProjectDir)$(OutDir). : .

Jednak $(TargetDir)zapewni katalog wyjściowy w jednym kroku.

Lista makr programu MSBuild firmy Microsoft dla bieżących i poprzednich wersji programu Visual Studio

Rich Shealer
źródło