简体   繁体   中英

How can I change a PCL into a .net Platform Standard Library in Visual Studio 2017?

I am trying to figure out how to change a portable .net class library into a .net platform standard library. There is a clickable link in the project settings that looks right it says "Target .net platform standard".

目标.net平台

The error which seems absurd to me is:

The project's targets cannot be changed. The selected targets require the project to opt-into NuGet 3.0 support, however, Visual Studio cannot automatically do this for you. Please uninstall all NuGet packages and try again.

Is there any way to do this that makes more sense than the absurd approach above of literally deleting all my references and then trying to add them back? I don't know how to take this project which I didn't write and convert it to to .net standard other than write all the references down on a piece of paper and then try to add them back again. Is that literally what I'm being told to do? Is there another way? Am I doing this wrong?

Secondly, even when I remove all references that can be removed, the project still won't convert. I removed Newtonsoft and all other references that can be removed, leaving only .net, system, and system.core, which are not removable.

I still get the same absurd error. The project I'm trying to modify is an open source project available on github, but I'm purposely trying to make this question more general so it could be useful to others who run into this "Target .net platform standard doesn't work at all" issue.

Same here

I struggled a lot with the exact same problem: The solution which worked best was the one provided by @Jasper H Bojsen

So I had to:

  • create a new project regarding the namespaces I was using in the pcl
  • ReNuggetManageDownloadPackagesReferences
  • and poof it compiled and I had no error

You may need to modify the project file by hand. It takes a bit of work, but here's some things which can help.

Before you start, backup your source if it is not hosted somewhere else.

  • First, make sure the project is using the same file format for the project file as you're about to create in the next step.

  • Next, create a new solution and project which targets the framework you're looking for, and add the NuGet packages you're using.

  • Close the new solution and open the one you're looking to change, and after it's loaded, unload the project in question. Edit the project file, and using either a diff tool or by hand open your new project file you created and compare the changes between the two project files. There are several key sections which you want to pay attention to.

  • Once you've finished editing the project file, close it and reload the project. Note any errors which may be returned, and correct as needed. If everything works correctly, try compiling.

This is just one possible solution, but from experience there's lots of little gotchas with project files, so don't take this as a definitive solution.

Below is an example of the difference between the two different project files, so moving from PCL -> Standard will be much easier than the reverse. (Note: These are just basic projects which I created quickly, and may not be representative of what you find.)

PCL

<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
      <PropertyGroup>
        <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
        <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
        <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
        <ProjectGuid>{66c3d80b-6265-468a-82e1-b76317f9a9a5}</ProjectGuid>
        <OutputType>Library</OutputType>
        <RootNamespace>PCLTest</RootNamespace>
        <AssemblyName>PCLTest</AssemblyName>
        <DefaultLanguage>en-US</DefaultLanguage>
        <FileAlignment>512</FileAlignment>
        <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
        <TargetFrameworkProfile></TargetFrameworkProfile>
        <TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
      </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>
        <None Include="project.json" />
        <!-- A reference to the entire .NET Framework is automatically included -->
      </ItemGroup>
      <ItemGroup>
        <Compile Include="Class1.cs" />
        <Compile Include="Properties\AssemblyInfo.cs" />
      </ItemGroup>
      <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
    </Project>

Standard

<Project Sdk="Microsoft.NET.Sdk">

      <PropertyGroup>
        <TargetFramework>netstandard1.4</TargetFramework>
      </PropertyGroup>

    </Project>

I know that this is probably not the answer you are hoping to get and I can't rule out that others have found different routes to success.

Anyhow. I had 6-7 PCL's that I wanted to move to .NET Standard. After fiddling around with it for a while trying to find the automagical way forward, I finally landed on a much more pragmatic approach.

What I did was to create a all new .NET Standard project with Visual Studio 2017 (v15.2 or later). Having the PCL project and the new .NET Standard project opened side-by-side (two monitors help here) I basically recreated the folder structure in the new project (using Visual Studio) copied over the files (using Explorer), added the files to the new project manually (using Visual Studio) as well as included and reestablished the references manually.

Also, remember to set the Assembly Name and Default Namespace to be identical to the PCL Assembly Name and Default Namespace . You get to these by right-clicking on the project and choosing Properties and the Application tab:

在此处输入图片说明

I know this sounds like boring work, but trust me, it doesn't take very long and the process is remarkably resistant to error. When the new project compiles you are done. If it doesn't, it's typically easy to figure out what is missing. Also, when it's works, you know that you've started from a clean slate and that you are not dragging over something that will come back and haunt you later.

Note : You might run into a System.* libraries missing in .NET Standard. If that happens see if you can add is as a NuGet's. They typically have a version 4.3.*. An example of this could be System.Net.Security .

It is also possible that you PCL relies on libraries that are not compatible with the version .NET Standard you decided on or any .NET Standard for that matter. In the first case try and see if you can live with a higher version .NET Standard. In the latter case you are currently out of luck, but look out for .NET Standard 2.0, which will have a much broader .NET API support.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM