web-dev-qa-db-ja.com

.NET Coreプロジェクトを取得してNuGet参照をコピーして出力をビルドする方法は?

.NET Coreを使用してプラグインシステムを作成しようとしていますが、私の要件の1つは、プラグインDLLをその依存関係とともにインストールのためにユーザーに配布できることです。ただし、dotnet publishをハックとして使用しなくても、NuGetの依存関係をビルドアーティファクトとして含めてビルドフォルダーに出力する方法はわかりません。 csprojでこれを指定する方法はありますか?

59
ron975

これをcsprojファイル内の<PropertyGroup>に追加して、NuGetアセンブリをビルドされた出力に強制的にコピーできます。

<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>

ただし、ビルド出力(bin/Release/netcoreapp*/*)は移植可能で配布可能ではないことに注意してください。dotnet publishの出力はそうです。しかし、あなたの場合、アセンブリをビルド出力にコピーすることはおそらくテスト目的で非常に便利です。ただし、ローカル変数を列挙する代わりに、DependencyContext apiを使用して、アプリケーションの依存関係グラフの一部であるDLLとその場所を解決することもできます。

100
Martin Ullrich

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を含めています。

8
Xeevis

私はこれをより簡単な方法で「解決」しました(回避策を作成しました)。

ビルド後

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|x64Release|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を取り出して、出力フォルダーにコピーします。仕事完了。

2
T.S.

上記の答えと併せて: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
0
seabass