wake-up-neo.com

Wie erhält man .NET Core-Projekte zum Kopieren von NuGet-Referenzen zum Erstellen von Ausgaben?

Ich versuche, ein Plugin-System mit .NET Core zu schreiben, und eine meiner Anforderungen besteht darin, das Plugin DLL zusammen mit seinen Abhängigkeiten an den Benutzer für die Installation verteilen zu können. Ich kann jedoch nicht herausfinden, wie ich meine NuGet-Abhängigkeiten als Build-Artefakt verwenden und in den Build-Ordner ausgeben lassen kann, ohne dotnet publish als Hack verwenden zu müssen. Gibt es eine Möglichkeit, dies im csproj anzugeben?

47
ron975

Sie können dies zu einem <PropertyGroup> in Ihrer csproj-Datei hinzufügen, um das Kopieren von NuGet-Assemblys in die erstellte Ausgabe zu erzwingen:

<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>

Beachten Sie jedoch, dass die Build-Ausgabe (bin/Release/netcoreapp*/*) nicht portierbar und verteilbar sein soll. Die Ausgabe von dotnet publish ist. In Ihrem Fall ist das Kopieren der Assemblys in die Build-Ausgabe jedoch möglicherweise zu Testzwecken sehr nützlich. Beachten Sie jedoch, dass Sie die DependencyContext-API auch verwenden können, um die DLLs und ihre Speicherorte, die Teil des Abhängigkeitsgraphen der Anwendung sind, aufzulösen, anstatt ein lokales Verzeichnis aufzulisten.

82
Martin Ullrich

Sie können PostBuildEvent verwenden, um die Modulbereitstellung beim Build zu automatisieren.

Um NuGet-Baugruppen im Build-Ordner zu erhalten, fügen Sie in csproj Ihres Moduls ein

<PropertyGroup>
    <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>

Definieren Sie die gewünschten Moduldateien mit Include/Exclude (Ändern Sie ggf. den Pfad).

<ItemGroup>
    <ModuleFiles
      Include="$(TargetDir)*.dll"
      Exclude="$(TargetDir)System*.dll;$(TargetDir)Microsoft*.dll"
      DestinationPath="$(SolutionDir)src\MyProject\Modules\MyModule\%(Filename)%(Extension)">
    </ModuleFiles>
</ItemGroup>

Setzen Sie Ihren Build-Ordner auf den Standard zurück und fügen Sie PostbuildEvent hinzu

<Target Name="PublishModule" AfterTargets="PostBuildEvent" Inputs="@(ModuleFiles)" Outputs="@(ModuleFiles->'%(DestinationPath)')">
    <WriteLinesToFile File="$(SolutionDir)src\[YOURAPP]\app_offline.htm" />
    <Copy SourceFiles="@(ModuleFiles)" DestinationFiles="@(ModuleFiles->'%(DestinationPath)')" />
    <Delete Files="$(SolutionDir)src\[YOURAPP]\app_offline.htm" />
</Target>

Ich füge app_offline zum Recyceln der App hinzu, wenn sie bereits läuft, um Fehler bei der Verwendung von Dateien zu vermeiden.

7
Xeevis

Hinzufügen

<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>

hat nicht funktioniert, aber dies zur Framework .csproj-Datei hinzugefügt:

<RestoreProjectStyle>PackageReference</RestoreProjectStyle>

tat.

3
Mike Brunner

Ich habe dies auf einfachere Art und Weise "gelöst".

Im Nachbau

dotnet publish "$(ProjectFileName)" --no-build -o pub
xcopy "$(ProjectDir)pub\3rdPartyProvider.*.dll" "$(OutDir)"

pub ist der Ordner, in dem Ihre veröffentlichten Inhalte zum Staging abgelegt werden sollen

HINWEIS: Je nach verwendeter Version von dotnet.exe ist der Befehl --no-build möglicherweise nicht verfügbar.

Beispielsweise nicht in Version 2.0.3 verfügbar. und verfügbar in v2.1.402. Ich weiß, dass VS2017 Update4 v2.0.3 hatte. Und Update8 hat 2.1.x

Update:

Das obige Setup funktioniert in der grundlegenden Debug-Umgebung. Um es in die Build-Server-/Produktionsumgebung zu bringen, ist jedoch noch mehr erforderlich. In diesem speziellen Beispiel, das ich lösen musste, bauen wir Release|x64 und Release|x86 getrennt auf. Also habe ich beides berücksichtigt. Um jedoch den Befehl post build dotnet publish zu unterstützen, habe ich zunächst RuntimeIdentifier zur Projektdatei hinzugefügt.

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
  <OutputPath>..\..\lib\</OutputPath>
  <RuntimeIdentifier>win-x64</RuntimeIdentifier>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
  <OutputPath>..\..\lib\</OutputPath>
  <RuntimeIdentifier>win-x86</RuntimeIdentifier>
</PropertyGroup>

Warum ich es brauchte und warum können Sie ohne es wegkommen? Ich brauchte das, weil mein build-Programm so eingestellt ist, dass es die Warnung MSB3270 abfängt und das Build fehlschlägt, wenn es erscheint. Diese Warnung besagt: "Hey, einige Dateien in Ihren Abhängigkeiten haben ein falsches Format". Erinnern Sie sich an das Ziel dieser Übung? Wir müssen Paketabhängigkeits-DLLs abrufen. In vielen Fällen spielt es keine Rolle, ob diese Warnung vorhanden ist, da der nachfolgende Postbuild keine Rolle spielt. Auch dies ist mein Build-Programm, das sich interessiert. Daher habe ich nur 2 Konfigurationen, die ich während des Produktionsaufbaus verwende, RuntimeIdentifier hinzugefügt.

Vollständiger Post-Build

if not exist "$(ProjectDir)obj\$(ConfigurationName)" mkdir "$(ProjectDir)obj\$(ConfigurationName)"
xcopy  "$(ProjectDir)obj\$(PlatformName)\$(ConfigurationName)" "$(ProjectDir)obj\$(ConfigurationName)" /E /R /Y

if $(ConfigurationName) == Release (
    dotnet publish "$(ProjectFileName)" --runtime win-$(PlatformName) --no-build -c $(ConfigurationName) -o pub --no-restore --no-dependencies
) else (
    dotnet publish "$(ProjectFileName)" --no-build -c $(ConfigurationName) -o pub --no-restore --no-dependencies
)

xcopy "$(ProjectDir)pub\my3rdPartyCompany.*.dll" "$(OutDir)" /Y /R

Erläuterung: dotnet publish sucht nach obj\Debug oder obj\Release. Wir haben es nicht während des Builds, weil Build obj\x64\Release oder obj\x86\Release erstellt. Zeile 1 und 2 mildern dieses Problem. In Zeile 3 weise ich dotnet.exe an, bestimmte Konfigurations- und Ziellaufzeiten zu verwenden. Ansonsten, wenn dies der Debug-Modus ist, kümmere ich mich nicht um Runtime-Sachen und Warnungen. Und in der letzten Zeile nehme ich einfach meine dlls und kopiere sie dann in den Ausgabeordner. Job erledigt.

0
T.S.

In Verbindung mit der obigen Antwort: Ich habe diese Funktion in der Befehlszeile Post-Build-Ereignis hervorragend ausgeführt: in Visual Studio . Sie durchläuft eine Auswahl von dlls (System *. DLL und Microsoft .dll) * und überspringt dann das Löschen bestimmter DLLs. System.Data.SqlClient.dll und System.Runtime.Loader.dll

for %%f in ($(OutDir)System*.dll $(OutDir)Microsoft*.dll) do if not %%f == $(OutDir)System.Data.SqlClient.dll if not %%f == $(OutDir)System.Runtime.Loader.dll del %%f
0
seabass