Wie kann Visual Studio eine DLL-Datei in das Ausgabeverzeichnis kopieren?


101

Ich habe ein Visual Studio C ++ - Projekt, das auf einer externen DLL-Datei basiert. Wie kann ich Visual Studio veranlassen, diese DLL-Datei beim Erstellen des Projekts automatisch in das Ausgabeverzeichnis (Debug / Release) zu kopieren?

Antworten:


90

Verwenden Sie eine Post-Build-Aktion in Ihrem Projekt und fügen Sie die Befehle zum Kopieren der fehlerhaften DLL hinzu. Die Post-Build-Aktion wird als Batch-Skript geschrieben.

Das Ausgabeverzeichnis kann als referenziert werden $(OutDir). Das Projektverzeichnis ist verfügbar als $(ProjDir). Versuchen Sie gegebenenfalls, relative Pfade zu verwenden, damit Sie Ihren Projektordner kopieren oder verschieben können, ohne die Aktion nach dem Erstellen zu unterbrechen.


25
Es ist auch erwähnenswert, dass er das Post-Build-Ereignis über Projekt> Eigenschaften> Build-Ereignisse> Post-Build-Ereignis festlegen kann.
Phil Booth


36
Für den Fall, dass der Link jemals unterbrochen wird: "xcopy / y" $ (ProjectDir) *. Dll "" $ (OutDir) "
Ass

Ich habe das oben Gesagte dahingehend geändert, wie ich den Befehl in meinen Instanzen persönlich verwende. Dieser Wille; Kopieren Sie schreibgeschützte Dateien, die für die Quellcodeverwaltung geeignet sind, und erstellen Sie das Zielverzeichnis (normalerweise nicht erforderlich). -> xcopy "$ (ProjectDir) *. dll" "$ (OutDir)" / i / r / y
Essen Sie am

8
Fügen Sie xCopy das Flag / d hinzu, um ein unnötiges erneutes Kopieren von Dateien zu verhindern, die sich im Ausgabeverzeichnis nicht geändert haben.
Zoey

43

$ (OutDir) stellte sich in VS2013 als relativer Pfad heraus, daher musste ich ihn mit $ (ProjectDir) kombinieren, um den gewünschten Effekt zu erzielen:

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

Übrigens können Sie die Skripte einfach debuggen, indem Sie am Anfang 'echo' hinzufügen und den erweiterten Text im Build-Ausgabefenster beobachten.


3
$ (TargetDir) kann $ (ProjectDir) $ (OutDir) ersetzen, da es sowieso eine Kombination aus beiden ist.
Person27

In meinem Fall ohne / d wurde ein Fehler "Zugriff verweigert" ausgelöst. Aber / d gemäß Dokumentation ist für Datum. Ich bin mir nicht sicher, was die Verbindung ist.
Ravi C

1
Durch Hinzufügen von / d wird das Überschreiben verhindert, wenn die Quelldatei älter oder mit einer vorhandenen Datei identisch ist. Der Fehler "Zugriff verweigert" kann auftreten, wenn das Ziel von einem anderen Prozess gesperrt wird.
Rich Shealer

7

Die Details im Kommentarbereich oben haben bei mir (VS 2013) nicht funktioniert, als versucht wurde, die Ausgabe-DLL von einem C ++ - Projekt in den Release- und Debug-Ordner eines anderen C # -Projekts innerhalb derselben Lösung zu kopieren.

Ich musste die folgende Post-Build-Aktion hinzufügen (Rechtsklick auf das Projekt mit einer DLL-Ausgabe) und dann Eigenschaften -> Konfigurationseigenschaften -> Build-Ereignisse -> Post-Build-Ereignis -> Befehlszeile

Jetzt habe ich diese beiden Zeilen hinzugefügt, um die Ausgabe-DLL in die beiden Ordner zu kopieren:

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

5

(Diese Antwort gilt nur für C #, nicht für C ++. Entschuldigung, ich habe die ursprüngliche Frage falsch verstanden.)

Ich bin schon einmal durch die DLL-Hölle gekommen. Meine endgültige Lösung bestand darin, die nicht verwalteten DLLs in der verwalteten DLL als binäre Ressourcen zu speichern und sie beim Start des Programms in einen temporären Ordner zu extrahieren und sie zu löschen, wenn sie entsorgt werden.

Dies sollte Teil der .NET- oder Pinvoke-Infrastruktur sein, da es so nützlich ist. Dadurch ist Ihre verwaltete DLL einfach zu verwalten, sowohl mit Xcopy als auch als Projektreferenz in einer größeren Visual Studio-Lösung. Sobald Sie dies getan haben, müssen Sie sich keine Gedanken mehr über Ereignisse nach dem Build machen.

AKTUALISIEREN:

Ich habe den Code hier in einer anderen Antwort veröffentlicht: https://stackoverflow.com/a/11038376/364818


1
Ich bin damit einverstanden, dass es Teil des Frameworks sein sollte (um DLLs statisch zu verknüpfen usw.). - Es ist erwähnenswert, dass das Speichern der DLL als Ressource und das anschließende Extrahieren zur Laufzeit in einigen Unternehmensumgebungen zu Problemen führen kann (insbesondere wenn diese fair sind) proaktive Antivirensoftware).
BrainSlugs83

1

Fügen Sie eine integrierte Kopie in die Datei project.csproj ein :

  <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 hat einen langfristigen Fehler. Verwenden Sie ProjectDir anstelle von SolutionDir
John_J.

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

Sie können auch auf einen relativen Pfad verweisen. Im nächsten Beispiel befindet sich die DLL in einem Ordner, der sich eine Ebene über dem Projektordner befindet. Wenn Sie mehrere Projekte haben, die die DLL in einer einzigen Lösung verwenden, wird die Quelle der DLL in einem gemeinsamen Bereich platziert, der erreichbar ist, wenn Sie eines davon als Startprojekt festlegen.

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

Die /yOption wird ohne Bestätigung kopiert. Die /dOption prüft, ob eine Datei im Ziel vorhanden ist und ob sie nur kopiert, wenn die Quelle einen neueren Zeitstempel als das Ziel hat.

Ich fand, dass zumindest in neueren Versionen von Visual Studio, wie z. B. VS2109, $(ProjDir)undefiniert ist und $(ProjectDir)stattdessen verwendet werden musste.

Das Auslassen eines Zielordners xcopysollte standardmäßig das Ausgabeverzeichnis sein. Das ist wichtig, um zu verstehen, dass die Vernunft $(OutDir)allein nicht hilfreich ist.

$(OutDir)Zumindest in neueren Versionen von Visual Studio ist dies als relativer Pfad zum Ausgabeordner definiert, z bin/x86/Debug. Wenn Sie es alleine als Ziel verwenden, wird ab dem Projektausgabeordner ein neuer Ordnersatz erstellt. Bsp. : … bin/x86/Debug/bin/x86/Debug.

Wenn Sie es mit dem Projektordner kombinieren, sollten Sie an den richtigen Ort gelangen. Bsp. : $(ProjectDir)$(OutDir).

Das $(TargetDir)Ausgabeverzeichnis wird jedoch in einem Schritt bereitgestellt.

Microsoft-Liste der MSBuild-Makros für aktuelle und frühere Versionen von Visual Studio

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.