迁移到 .csproj SDK 破坏了从 NuGet 包导入 DLL 的功能。

huangapple go评论82阅读模式
英文:

Migrating to .csproj SDK breaks import of dlls from nuget package

问题

以下是您提供的内容的中文翻译:

最近,我尝试使用 .net 升级助手 将我的 .csproj 文件升级到 SDK 标准。最初似乎可以工作,我的所有 NuGet 依赖项也随之而来。

然而,当我尝试构建我的项目(目标为 .net48)时,来自 NuGet 包的 DLL 不包括在输出目录中。我已经在网络上寻找解决方案,但大多数解决方案似乎表明它们应该存在。我遇到问题的具体包是 RavenDB.Database v2.5.25041。它是一个需要这个特定版本的测试套件的一部分,所以我不幸无法升级它。除非 DLL 存在于输出目录中(手动复制进行测试),否则测试也无法运行并报告缺少程序集。

在 SDK 迁移之前对项目进行构建可以正常工作,输出目录包括这些 DLL。是否有人知道为什么新版本中工作方式不同,以及如何解决这个问题?

编辑:

这是转换后的 .csproj 文件:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net48</TargetFramework>
    <OutputType>Library</OutputType>
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System.Data.Services.Client" />
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="EntityFramework" Version="6.4.4" />
    <PackageReference Include="RavenDB.Database" Version="2.5.25041" />
    <PackageReference Include="RavenDB.Embedded" Version="2.5.25041" />
  </ItemGroup>
</Project>

编辑2:

转换前的 .csproj 文件(警告,很大):

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="..\..\packages\EntityFramework.6.4.4\build\EntityFramework.props" Condition="Exists('..\..\packages\EntityFramework.6.4.4\build\EntityFramework.props')" />
  <Import Project="..\..\packages\JunitXml.TestLogger.2.1.81\build\net45\JUnitXml.TestLogger.props" Condition="Exists('..\..\packages\JunitXml.TestLogger.2.1.81\build\net45\JUnitXml.TestLogger.props')" />
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{7A3590CE-A43F-4A69-B520-27402FDD9F87}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>Sti.TestUtils</RootNamespace>
    <AssemblyName>Sti.TestUtils</AssemblyName>
    <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <Deterministic>true</Deterministic>
    <NuGetPackageImportStamp>
    </NuGetPackageImportStamp>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
      <HintPath>..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll</HintPath>
    </Reference>
    <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
      <HintPath>..\..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll</HintPath>
    </Reference>
    <Reference Include="Microsoft.Data.Edm, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <HintPath>..\..\packages\Microsoft.Data.Edm.5.2.0\lib\net40\Microsoft.Data.Edm.dll</HintPath>
    </Reference>
    <Reference Include="Microsoft.Data.OData, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <HintPath>..\..\packages\Microsoft.Data.OData.5.2.0\lib\net40\Microsoft.Data.OData.dll</HintPath>
    </Reference>
    <Reference Include="Microsoft.WindowsAzure.Configuration, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <HintPath>..\..\packages\Microsoft.WindowsAzure.ConfigurationManager.1.8.0.0\lib\net35-full\Microsoft.WindowsAzure.Configuration.dll</HintPath>
    </Reference>
    <Reference Include="Microsoft.WindowsAzure.Storage, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <HintPath>..\..\packages\WindowsAzure.Storage.2.0.0.0\lib\net40\Microsoft.WindowsAzure.Storage.dll</HintPath>
    </Reference>
    <Reference Include

<details>
<summary>英文:</summary>

Recently I tried to upgrade my .csproj files to SDK standard using [.net upgrade assistant](https://dotnet.microsoft.com/en-us/platform/upgrade-assistant). Initially it seems to work and all my nuget dependencies came along for the ride.

However when I try to build my project (targeting `.net48`) the dlls from the nuget package are not included in the output directory. I&#39;ve been looking for solutions around the web, but most of them seem to indicate that they should be present. The specific package I&#39;m having problems with is `RavenDB.Database v2.5.25041`. It is part of a test suite that needs this specific version so I cannot unfortunately upgrade it. The tests also do not run and complain about missing assemblies unless the dlls are present in the output directory (testet by manually copying them).

Running a build on the project before the SDK-migration works fine and the output directory includes those dlls. Does anyone know why this work differently in the new version and how can I resolve it?

Edit:

This is the `.csproj` file after conversion:

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net48</TargetFramework>
<OutputType>Library</OutputType>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<ItemGroup>
<Reference Include="System.Data.Services.Client" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="EntityFramework" Version="6.4.4" />
<PackageReference Include="RavenDB.Database" Version="2.5.25041" />
<PackageReference Include="RavenDB.Embedded" Version="2.5.25041" />
</ItemGroup>
</Project>


Edit2:
The `.csproj` file before conversion (warning, big):

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="....\packages\EntityFramework.6.4.4\build\EntityFramework.props" Condition="Exists('....\packages\EntityFramework.6.4.4\build\EntityFramework.props')" />
<Import Project="....\packages\JunitXml.TestLogger.2.1.81\build\net45\JUnitXml.TestLogger.props" Condition="Exists('....\packages\JunitXml.TestLogger.2.1.81\build\net45\JUnitXml.TestLogger.props')" />
<Import Project="$(MSBuildExtensionsPath)$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7A3590CE-A43F-4A69-B520-27402FDD9F87}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Sti.TestUtils</RootNamespace>
<AssemblyName>Sti.TestUtils</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug&lt;/OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release&lt;/OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>....\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll</HintPath>
</Reference>
<Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>....\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Data.Edm, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>....\packages\Microsoft.Data.Edm.5.2.0\lib\net40\Microsoft.Data.Edm.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Data.OData, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>....\packages\Microsoft.Data.OData.5.2.0\lib\net40\Microsoft.Data.OData.dll</HintPath>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Configuration, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>....\packages\Microsoft.WindowsAzure.ConfigurationManager.1.8.0.0\lib\net35-full\Microsoft.WindowsAzure.Configuration.dll</HintPath>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Storage, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>....\packages\WindowsAzure.Storage.2.0.0.0\lib\net40\Microsoft.WindowsAzure.Storage.dll</HintPath>
</Reference>
<Reference Include="Raven.Abstractions, Version=2.5.0.0, Culture=neutral, PublicKeyToken=37f41c7f99471593, processorArchitecture=MSIL">
<HintPath>....\packages\RavenDB.Client.2.5.25041\lib\net45\Raven.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Raven.Client.Embedded, Version=2.5.0.0, Culture=neutral, PublicKeyToken=37f41c7f99471593, processorArchitecture=MSIL">
<HintPath>....\packages\RavenDB.Embedded.2.5.25041\lib\net45\Raven.Client.Embedded.dll</HintPath>
</Reference>
<Reference Include="Raven.Client.Lightweight, Version=2.5.0.0, Culture=neutral, PublicKeyToken=37f41c7f99471593, processorArchitecture=MSIL">
<HintPath>....\packages\RavenDB.Client.2.5.25041\lib\net45\Raven.Client.Lightweight.dll</HintPath>
</Reference>
<Reference Include="Raven.Database, Version=2.5.0.0, Culture=neutral, PublicKeyToken=37f41c7f99471593, processorArchitecture=MSIL">
<HintPath>....\packages\RavenDB.Database.2.5.25041\lib\net45\Raven.Database.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Core" />
<Reference Include="System.Data.Services.Client" />
<Reference Include="System.Spatial, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>....\packages\System.Spatial.5.2.0\lib\net40\System.Spatial.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('....\packages\JunitXml.TestLogger.2.1.81\build\net45\JUnitXml.TestLogger.props')" Text="$([System.String]::Format('$(ErrorText)', '....\packages\JunitXml.TestLogger.2.1.81\build\net45\JUnitXml.TestLogger.props'))" />
<Error Condition="!Exists('....\packages\EntityFramework.6.4.4\build\EntityFramework.props')" Text="$([System.String]::Format('$(ErrorText)', '....\packages\EntityFramework.6.4.4\build\EntityFramework.props'))" />
<Error Condition="!Exists('....\packages\EntityFramework.6.4.4\build\EntityFramework.targets')" Text="$([System.String]::Format('$(ErrorText)', '....\packages\EntityFramework.6.4.4\build\EntityFramework.targets'))" />
</Target>
<Import Project="....\packages\EntityFramework.6.4.4\build\EntityFramework.targets" Condition="Exists('....\packages\EntityFramework.6.4.4\build\EntityFramework.targets')" />
</Project>


</details>
# 答案1
**得分**: 1
你正在构建一个*库*项目。在构建库时,传递包的完整输出分辨率不正常,因为在存在*应用程序*项目之前,它不知道全部的情况。您的一些传递包可能对不同平台有不同的输出;*应用程序*选择目标平台,而不是任何库。
添加一个*应用程序*项目(只需一个控制台 exe 就可以),将您的库作为项目引用,并查看*该*项目的输出文件夹。如果您的测试项目不起作用:请检查您的测试项目是否使用项目或软件包引用到您库的引用,而不是到您库输出的 dll 的引用。
如果仍然有*特定的问题*,请检查翻译中可能不需要*构建*,但在运行时实际上仍然可能需要的许多省略引用中是否有软件包可用。
<details>
<summary>英文:</summary>
You are building a *library* project. It is normal for full output resolution of transitive packages not to happen when building a library, because until an *application* project exists, it doesn&#39;t know the full story. Some of your transitive packages might have different outputs for different platforms; the *application* chooses the target platform, not any of the libraries.
Add an *application* project (just a console exe would do) that *references* your library as a project-reference, and look at the output folder of *that*. If your test project isn&#39;t working: check that your test project is using a project or package reference to your library, and not a dll reference to your library&#39;s output.
If there are *specific things* that still don&#39;t work, check whether there are package available for some of the many omitted references in the translation that might not be needed for *build*, but might actually still be needed at runtime.
</details>
# 答案2
**得分**: 1
我成功找到了解决此特定情况的方法。由于dll文件是作为NuGet包的一部分下载的,您可以通过将以下内容添加到最终程序集的.csproj文件中,强制dotnet将它们包括在构建输出中。这意味着实际构建成可执行文件的程序集。
添加包引用并将GeneratePathProperty设置为True。
```xml
<PackageReference Include="RavenDB.Database" Version="2.5.25041">
<GeneratePathProperty>True</GeneratePathProperty>
</PackageReference>

然后使用生成的路径属性引用丢失的dll文件。

<ItemGroup>
  <Reference Include="Esent.Interop">
    <HintPath>$(PkgRavenDB_Database)\lib\net45\Esent.Interop.dll</HintPath>
  </Reference>
  <Reference Include="ICSharpCode.NRefactory">
    <HintPath>$(PkgRavenDB_Database)\lib\net45\ICSharpCode.NRefactory.dll</HintPath>
  </Reference>
  <Reference Include="ICSharpCode.NRefactory.CSharp">
    <HintPath>$(PkgRavenDB_Database)\lib\net45\ICSharpCode.NRefactory.CSharp.dll</HintPath>
  </Reference>
  <Reference Include="Lucene.Net">
    <HintPath>$(PkgRavenDB_Database)\lib\net45\Lucene.Net.dll</HintPath>
  </Reference>
  <Reference Include="Lucene.Net.Contrib.Spatial.NTS">
    <HintPath>$(PkgRavenDB_Database)\lib\net45\Lucene.Net.Contrib.Spatial.NTS.dll</HintPath>
  </Reference>
  <Reference Include="Spatial4n.Core.NTS">
    <HintPath>$(PkgRavenDB_Database)\lib\net45\Spatial4n.Core.NTS.dll</HintPath>
  </Reference>
</ItemGroup>

这将使构建工具指向dll文件,无论它们保存在何处下载的NuGet包。有关GeneratePathProperty的更多信息,请阅读msdocs上的说明

英文:

I managed to find a workaround for this specific case. Since the dlls are downloaded as part of the nuget package you can force dotnet to include them in the build output by adding the following to the .csproj file of the final assembly. Meaning the assembly that is actually built to an executable.

Add the package reference and set GeneratePathProperty to true.

&lt;PackageReference Include=&quot;RavenDB.Database&quot; Version=&quot;2.5.25041&quot;&gt;
&lt;GeneratePathProperty&gt;True&lt;/GeneratePathProperty&gt;
&lt;/PackageReference&gt;

Then reference the missing dlls using the generated path property.

&lt;ItemGroup&gt;
&lt;Reference Include=&quot;Esent.Interop&quot;&gt;
&lt;HintPath&gt;$(PkgRavenDB_Database)\lib\net45\Esent.Interop.dll&lt;/HintPath&gt;
&lt;/Reference&gt;
&lt;Reference Include=&quot;ICSharpCode.NRefactory&quot;&gt;
&lt;HintPath&gt;$(PkgRavenDB_Database)\lib\net45\ICSharpCode.NRefactory.dll&lt;/HintPath&gt;
&lt;/Reference&gt;
&lt;Reference Include=&quot;ICSharpCode.NRefactory.CSharp&quot;&gt;
&lt;HintPath&gt;$(PkgRavenDB_Database)\lib\net45\ICSharpCode.NRefactory.CSharp.dll&lt;/HintPath&gt;
&lt;/Reference&gt;
&lt;Reference Include=&quot;Lucene.Net&quot;&gt;
&lt;HintPath&gt;$(PkgRavenDB_Database)\lib\net45\Lucene.Net.dll&lt;/HintPath&gt;
&lt;/Reference&gt;
&lt;Reference Include=&quot;Lucene.Net.Contrib.Spatial.NTS&quot;&gt;
&lt;HintPath&gt;$(PkgRavenDB_Database)\lib\net45\Lucene.Net.Contrib.Spatial.NTS.dll&lt;/HintPath&gt;
&lt;/Reference&gt;
&lt;Reference Include=&quot;Spatial4n.Core.NTS&quot;&gt;
&lt;HintPath&gt;$(PkgRavenDB_Database)\lib\net45\Spatial4n.Core.NTS.dll&lt;/HintPath&gt;
&lt;/Reference&gt;

</ItemGroup>

This will point the build tools to the dlls regardless of where it saves downloaded nuget packages.
Read more about GeneratePathProperty on msdocs

答案3

得分: 0

这是预期行为-请参阅https://learn.microsoft.com/en-us/nuget/consume-packages/package-restore#restore-packages,特别是:

> 恢复成功后:
>
> - 对于使用&lt;PackageReference&gt;的项目,软件包存在于本地 global-packages 文件夹中,并重新创建项目 obj/project.assets.json 文件。
> - 对于使用 packages.config 的项目,软件包出现在项目的 packages 文件夹中。
> - 项目现在应该能够成功构建。

通过切换到 PackageReference,您已更改了还原的行为,使其更适应现代设置,其中软件包是从全局缓存中消耗的(通常是 %userprofile%\.nuget\packages)。

英文:

This is expected behaviour - see https://learn.microsoft.com/en-us/nuget/consume-packages/package-restore#restore-packages, in particular:

> After a successful restore:
>
> - For projects that use &lt;PackageReference&gt;, the package is present in the local global-packages folder, and the project
> obj/project.assets.json file is recreated.
> - For projects that use packages.config, the package appears in the project's packages folder.
> - The project should now build successfully.

By switching to PackageReference, you've changed the behaviour of the restore to the more modern setup where packages are consumed from a global cache (typically %userprofile%\.nuget\packages)

huangapple
  • 本文由 发表于 2023年2月8日 17:06:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/75383417.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定