.NET Coreを使用してプラグインシステムを作成しようとしていますが、私の要件の1つは、プラグインDLLをその依存関係とともにインストールのためにユーザーに配布できることです。ただし、dotnet publish
をハックとして使用しなくても、NuGetの依存関係をビルドアーティファクトとして含めてビルドフォルダーに出力する方法はわかりません。 csprojでこれを指定する方法はありますか?
これをcsprojファイル内の<PropertyGroup>
に追加して、NuGetアセンブリをビルドされた出力に強制的にコピーできます。
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
ただし、ビルド出力(bin/Release/netcoreapp*/*
)は移植可能で配布可能ではないことに注意してください。dotnet publish
の出力はそうです。しかし、あなたの場合、アセンブリをビルド出力にコピーすることはおそらくテスト目的で非常に便利です。ただし、ローカル変数を列挙する代わりに、DependencyContext
apiを使用して、アプリケーションの依存関係グラフの一部であるDLLとその場所を解決することもできます。
PostBuildEventを使用して、ビルド時のモジュール展開を自動化できます。
ビルドフォルダーのNuGetアセンブリを取得するには、モジュールのcsprojを追加します
<PropertyGroup>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
Include/Excludeを使用して、必要なモジュールファイルの場所を定義します(必要に応じてパスを変更します)
<ItemGroup>
<ModuleFiles
Include="$(TargetDir)*.dll"
Exclude="$(TargetDir)System*.dll;$(TargetDir)Microsoft*.dll"
DestinationPath="$(SolutionDir)src\MyProject\Modules\MyModule\%(Filename)%(Extension)">
</ModuleFiles>
</ItemGroup>
ビルドフォルダーをデフォルトにリセットし、PostbuildEventを追加します
<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>
ファイルの使用中のエラーを回避するために、既に実行中のアプリをリサイクルするためにapp_offlineを含めています。
私はこれをより簡単な方法で「解決」しました(回避策を作成しました)。
ビルド後
dotnet publish "$(ProjectFileName)" --no-build -o pub
xcopy "$(ProjectDir)pub\3rdPartyProvider.*.dll" "$(OutDir)"
pub
は、公開されたものをステージングに使用するフォルダーです
注:使用するdotnet.exe
のバージョンによっては、コマンド--no-build
が使用できない場合があります。
たとえば、v2.0.3では使用できません。 v2.1.402で利用可能です。 VS2017 Update4にはv2.0.3があったことを知っています。 Update8には2.1.xがあります
更新:
上記のセットアップは基本的なデバッグ環境で機能しますが、ビルドサーバー/実稼働環境に組み込むにはさらに必要です。私が解決しなければならなかったこの特定の例では、Release|x64
とRelease|x86
を別々にビルドします。だから私は両方を説明しました。しかし、ポストビルドdotnet publish
コマンドをサポートするために、最初にRuntimeIdentifier
をプロジェクトファイルに追加しました。
<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>
なぜ私はそれを必要とし、なぜあなたはそれなしで逃げられるのですか? myビルドプログラムが警告MSB327をインターセプトするように設定されており、表示された場合はビルドに失敗するため、これが必要でした。この警告は、「あなたの依存関係の一部のファイルの形式が間違っている」と述べています。しかし、この演習の目標を覚えていますか?パッケージの依存関係DLLをプルする必要があります。多くの場合、次のポストビルドは関係ないため、この警告が表示されていても問題ありません。繰り返しますが、これは気にする私のビルドプログラムです。そのため、実動ビルド中に使用する2つの構成にRuntimeIdentifier
のみを追加しました。
フルポストビルド
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
説明:dotnet publishはobj\Debug
またはobj\Release
を探しています。ビルドではobj\x64\Release
またはobj\x86\Release
が作成されるため、ビルド中にそれはありません。 1行目と2行目はこの問題を軽減します。 3行目では、dotnet.exe
に特定の構成とターゲットランタイムを使用するように指示しています。それ以外の場合、これがデバッグモードの場合、ランタイムの問題や警告は気にしません。そして最後の行では、dllを取り出して、出力フォルダーにコピーします。仕事完了。
上記の答えと併せて:Visual Studioのビルド後のイベントコマンドライン:でこれがうまく機能しています。選択されたdll(System * .dllおよびMicrosoft。dll)*をループし、特定のdllの削除をスキップします。 System.Data.SqlClient.dllおよび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