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?
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.
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.
Hinzufügen
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
hat nicht funktioniert, aber dies zur Framework .csproj-Datei hinzugefügt:
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
tat.
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.
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