C# 如何让.NET核心项目将NuGet引用复制到生成输出?

C# 如何让.NET核心项目将NuGet引用复制到生成输出?,c#,msbuild,.net-core,nuget,csproj,C#,Msbuild,.net Core,Nuget,Csproj,我正在尝试用.NET内核编写一个插件系统,我的要求之一是能够将插件DLL及其依赖项分发给用户进行安装 但是,我不知道如何将我的NuGet依赖项作为构建工件包含,并将它们输出到构建文件夹,而不必使用dotnet publish作为一种攻击。有什么方法可以在.csproj文件(项目文件)中指定此项吗?您可以将此项添加到csproj文件内的中,以强制将NuGet程序集复制到生成输出: <CopyLocalLockFileAssemblies>true</CopyLocalLockFi

我正在尝试用.NET内核编写一个插件系统,我的要求之一是能够将插件DLL及其依赖项分发给用户进行安装


但是,我不知道如何将我的NuGet依赖项作为构建工件包含,并将它们输出到构建文件夹,而不必使用
dotnet publish
作为一种攻击。有什么方法可以在.csproj文件(项目文件)中指定此项吗?

您可以将此项添加到csproj文件内的
中,以强制将NuGet程序集复制到生成输出:

<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
true

但是,请注意,构建输出(
bin/Release/netcoreapp*/*
)不应是可移植和可分发的,而
dotnet publish
的输出是可移植的。但在您的情况下,将程序集复制到生成输出对于测试目的可能非常有用。但请注意,您也可以使用
DependencyContext
api解析DLL及其位置,这些DLL及其位置是应用程序依赖关系图的一部分,而不是枚举本地目录。

您可以使用PostBuildEvent在生成时自动部署模块

要在模块的生成文件夹add-incsproj中获取NuGet程序集

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

真的
使用Include/Exclude(根据需要修改路径)定义所需的模块文件


将生成文件夹重置为默认值并添加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>

如果应用程序已经运行,我会将其包括在离线状态,以循环使用,以避免文件使用错误。

我以更简单的方式“解决”(创建了解决方案)

建成后

dotnet发布“$(ProjectFileName)”--无构建-o发布
xcopy“$(ProjectDir)pub\3rdPartyProvider.*.dll”“$(OutDir)”
pub
是您希望将已发布的内容用于暂存的文件夹

注意:根据您使用的
dotnet.exe
版本的不同,命令
--无生成可能不可用

例如,在v2.0.3中不可用;并在v2.1.402中提供。我知道VS2017更新4有v2.0.3。而Update8有2.1.x版本

更新:

上述设置将在基本调试环境中工作,但要将其放入构建服务器/生产环境中,还需要更多。在我必须解决的这个特定示例中,我们分别构建
Release | x64
Release | x86
。所以我把两者都考虑进去了。但是为了支持后期构建
dotnetpublish
命令,我首先将
RuntimeIdentifier
添加到项目文件中


..\..\lib\
win-x64
..\..\lib\
win-x86
为什么我需要它,为什么你可以不需要它?我之所以需要它,是因为我的构建程序被设置为拦截警告MSB3270,如果出现警告,构建就会失败。此警告表示,“嘿,依赖项中的某些文件格式错误”。但是你还记得这个练习的目的吗?我们需要拉包依赖DLL。在很多情况下,这个警告是否存在并不重要,因为后续构建并不重要。同样,这是我关心的构建程序。因此,我只在生产构建期间使用的两个配置中添加了
RuntimeIdentifier

完整后期构建

如果不存在“$(ProjectDir)obj\$(配置名称)“mkdir”$(ProjectDir)obj\$(配置名称)”
xcopy“$(ProjectDir)obj\$(PlatformName)\$(ConfigurationName)”“$(ProjectDir)obj\$(ConfigurationName)”/E/R/Y
如果$(ConfigurationName)=发布(
dotnet发布“$(ProjectFileName)”--运行时win-$(平台名)--无构建-c$(配置名)-o发布--无恢复--无依赖项
)否则(
dotnet发布“$(ProjectFileName)”--无构建-c$(配置名称)-o发布--无恢复--无依赖项
)
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复制到输出文件夹中。工作完成。

结合上述答案: 我在VisualStudio中的后期生成事件命令行:中实现了这一功能。 它在选定的dll(System*.dll和Microsoft.dll)*上循环,然后跳过特定dll的删除。System.Data.SqlClient.dll和System.Runtime.Loader.dll

添加

true
不起作用,但将其添加到Framework.csproj文件:

<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
PackageReference

是的。

我正在使用.NET 5,下面是我对类似问题的解决方案

结构: Project-A(包含Selenium Nuget引用和Selenium代码) Project-B(单元测试项目,它调用Project-A中的方法)

问题: 构建解决方案时,chromedriver.exe文件出现在Project-A-bin文件夹中,但不会复制到Project-B-bin文件夹中,因此无法执行单元测试。引发异常,说明找不到chromedriver.exe

解决方案: 修改SejEntudio中的属性,以便只考虑“CordTrand文件”;分析人员的私人资产。默认值为“contentfiles;分析仪;未指定时生成。这现在意味着可以将生成的输出文件流到父引用项目,但不能流到内容文件或分析器,因为“生成”以前也被视为私有资产,不会流到父项目

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
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
<ItemGroup>
  <PackageReference Include="Selenium.Support" Version="3.141.0" />
  <PackageReference Include="Selenium.WebDriver" Version="3.141.0" />
  <PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="87.0.4280.8800" />
</ItemGroup>
<ItemGroup>
  <PackageReference Include="Selenium.Support" Version="3.141.0" />
  <PackageReference Include="Selenium.WebDriver" Version="3.141.0" />
  <PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="87.0.4280.8800">
    <PrivateAssets>contentfiles;analyzers</PrivateAssets>
  </PackageReference>
</ItemGroup>