it-swarm.com.de

Visual Studio kopiert keine Inhaltsdateien aus Projekten, auf die indirekt verwiesen wird

Ich habe folgende Projektstruktur:

Library1 <--[project reference]-- Library2 <--[ref]-- Executable
--------                          --------            ----------
ContentFile                      .cs files           .cs files
.cs files

Alle Projektreferenzen haben CopyLocal = true.

Wenn ich das Projekt erstelle, wird ContentFile in das Ausgabeverzeichnis von Library2 kopiert, nicht jedoch in das Ausgabeverzeichnis von Executable, was bedeutet, dass die ausführbare Datei bei Ausführung der Anwendung ContentFile fehlt.

Warum wird die Inhaltsdatei in das Ausgabeverzeichnis von Library2 kopiert, nicht jedoch in das von Executable? Gibt es eine Möglichkeit, es auch auf Letzteres zu kopieren (ich würde das gerne tun, ohne Ereignisse zu erstellen, weil ich sicher bin, dass die Leute das vergessen werden)?

Ich suche eine vernünftige und wartbare Lösung; Eine, die beim Hinzufügen neuer Projekte oder neuer Inhaltsdateien, auf die indirekt verwiesen wird, nur minimalen Aufwand erfordert, sodass es so unwahrscheinlich wie möglich ist, diese einfach zu vergessen.

Verwenden von Post-Build-Ereignissen (wie xcopy ../Library/bin/Debug/SomeDll.dll bin/Debug); und das manuelle Setzen des Ausgabeverzeichnisses von Projekten auf $(SolutionDir)/bin/... anstelle des Standardverzeichnisses (pro Projekt) ist schnell zu einem großen Durcheinander geworden. Das Hinzufügen der Inhaltsdateien als Links im "Hauptprojekt" war ebenfalls zu mühsam. Es wäre in Ordnung, wenn C # dieselbe Standardeinstellung für die Ausgabedatei hätte wie Visual C++ (d. H. $SolutionDir/$Platform/$Configuration), dies ist jedoch nicht der Fall.

Ich habe auch darüber nachgedacht, die MSBuild-Standardprozedur überhaupt nicht zu verwenden und ein benutzerdefiniertes Build-Ziel (wie die Verwendung von gcc in Atmel Studio) zu schreiben, bin aber überhaupt nicht weit gekommen. Außerdem möchte ich, dass die Standardbefehle "Build" und "Debug" von Visual Studio wie gewohnt funktionieren.


AKTUALISIEREN:

Hier erfahren Sie mehr darüber, was ich tue.

Ich habe eine Lösung mit einem Executable Projekt. Darüber hinaus gibt es eine Reihe von Projekten, die Sie Plugins nennen können. Executable verweist über eine verwaltete Projektreferenz auf alle diese Plugin.

Da die Plugin-Projekte auf die ausführbare Datei zugeschnitten sind, aber wiederverwendbare Komponenten enthalten können, wird die Hauptfunktionalität häufig in einem External -Projekt implementiert, sodass das Plugin -Projekt nur ein Wrapper ist (nicht immer).

Bei diesen External Projekten werden manchmal native DLLs von Drittanbietern verwendet. Diese DLLs werden dann dem Projekt External als Inhaltsdatei hinzugefügt und haben Copy to output dir auf Copy always gesetzt. Die Struktur sieht also wie im obigen Diagramm aus:

External <---------------[is not aware of]--------------------+
--------                                                      |
.cs files <--[reference]-- PluginWrapper <--[reference]-- Executable
"Native DLL"               -------------                  ----------
                           .cs files                      .cs files

Das Seltsame ist, dass die "native DLL" in das Ausgabeverzeichnis von External kopiert wird (offensichtlich), sowiePluginWrapper, aber nicht Executable 's.

Der Workflow des Entwicklers würde dann darin bestehen, ein External zu schreiben, das als vollständig isolierte Entität funktioniert (sie werden sehr oft wiederverwendet), und es zu einem Wrap zusammenzufassen mit einem PluginWrapper und fügen Sie dann nur einen Projektverweis auf PluginWrapper bis Executable hinzu. Ich finde es seltsam, dass dies anscheinend so ungewöhnlich ist.

Ich dachte, dass das Problem möglicherweise durch Bearbeiten von MSBuild-Ziel-XML von Executable (einschließlich indirekt referenzierter Inhaltsdateien) behoben werden könnte.

Ich möchte vielleicht die vorgeschlagenen DLLs als eingebettete Ressourcen zu den Projekten hinzufügen, aber das Einbetten nativer DLLs scheint mir seltsam. Am Ende ist es möglicherweise die sinnvollste Lösung, den Workflow des Entwicklers zu ändern, indem das '[ist nicht bekannt]' aus dem obigen Diagramm entfernt und ein Projektverweis auf External hinzugefügt wird, wie Brenda Bell vorgeschlagen hat, auch wenn dies nicht der Fall ist Ideal.

Update 2

Beachten Sie, dass die Idee der eingebetteten Ressource möglicherweise nicht in allen Fällen funktioniert. Wenn eine Abhängigkeit im Verzeichnis der ausführbaren Datei abgelegt werden muss (nicht cwd oder so), funktioniert dies möglicherweise nicht, da im Installationsordner Administratorrechte fehlen (um die Datei von der eingebetteten Ressource zu entpacken). Klingt komisch, aber dies war ein ernstes Problem mit einer der Bibliotheken von Drittanbietern, die wir verwendet haben.

31
dialer

Fügen Sie den Verweis Library1 zum ausführbaren Projekt hinzu.

19
Brenda Bell

BEARBEITEN:

Sie können den gesamten Inhalt in einem separaten Projekt ablegen, alle Einträge auf "Inhalt" und "Immer kopieren" setzen und auf dieses Projekt in External and Executable verweisen

-

IMO suchen Sie nach eingebetteten Ressourcen, nicht nach Inhaltsdateien.

Wenn Sie Bibliothek 1 kompilieren, werden die Inhaltsdateien in den Ordner "bin" verschoben. Beim Kompilieren von Bibliothek 2 erkennt der Compiler den Code, auf den verwiesen wird, und schließt ihn ein (Bibliothek 1.dll). Die Inhaltsdateien werden jedoch nicht erkannt, da sie in Bibliothek 2 nirgendwo erwähnt werden. Dasselbe gilt für das Verknüpfen von Bibliothek 2 mit der ausführbaren Datei.

Wenn Ihre Inhaltsdateien relativ klein sind (Symbole, Vorlagen usw.) und Sie sich nicht vorstellen können, sie zu bearbeiten, wenn Sie den Quellcode verlieren, können Sie sie als Ressourcen einbetten und eine öffentliche Methode zur Rückgabe der Inhalte bereitstellen, z :

 public static Stream GetResourceContent(string rName){
     string resName = System.Reflection.Assembly
         .GetExecutingAssembly().GetManifestResourceNames()
         .FirstOrDefault(rn => rn.EndsWith("."+rName));
    if(resName!=null)
        return System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resName);
    else
        return null;
}

Wenn sich Ihr Inhalt zwangsläufig ändert, z. B. Vorlagen usw., sollten Sie eine Kopie in das ausführbare Projekt aufnehmen

5
Sten Petrov

Eine andere Möglichkeit wäre, ContentFile als Ressource in die Assembly Library1 einzubetten und mit Assembly.GetManifestResource () zu extrahieren.

Weitere Informationen finden Sie unter diesen Links:

http://www.attilan.com/2006/08/accessing-embedded-resources-using.html

http://blogs.msdn.com/b/alexdan/archive/2007/12/19/loading-embedded-resources-in-c-using-getmanifestresourcestream.aspx

3
MvdD

Eine Variante von Brendas Antwort wäre, die Inhaltsdatei (en) der Bibliothek1 als Link (s) in das ausführbare Projekt einzufügen. Sie hätten immer noch die Einträge im Projekt, müssten aber nicht mehrere Kopien jeder Datei verwalten.

1
Chris Peach

Möglicherweise verweisen Sie in diesem Fall nur aus einer XAML-Datei auf Library1. Visual Studio erkennt die Verwendung nicht. Fügen Sie auch eine Referenz in den Code ein, z. durch Anwenden des Namensattributs

0
Jens