Jump to content

How do I add .NET 5.0 Framework for existing project?


MJW

Recommended Posts

I tried to build an existing plugin now that I've installed the new version of PDN that uses .NET 5.0. Naturally, I got the usual slew of errors that comes from building using a version of PDN that's different from the framework for the plugin project. I opened the project's Properties to change the target framework, but 5.0 was not among the choices. From the list, I selected "Install other frameworks" which semi-helpfully took me to a webpage of SDK and runtime downloads. Just to be safe, I installed all the 5.0 stuff. I again tried selecting 5.0 from the framework list, but it still wasn't there. I restarted Visual Studio, which didn't help. I was able to build a console app that used 5.0, so 5.0 must be installed.

 

I've installed new frameworks in the past, and though I don't recall the details, I don't remember it being especially difficult. The answer is probably easy and obvious, but this is the kind of obnoxious problem I hate like the plague have absolutely no patience for.

 

 

Link to comment
Share on other sites

Never detected a possibility in VS2019 to switch forth and back from 4.7.2 (and lower) to 5 (and upper). So to I'm just replacing the content of the 4.7.2 project file with a 5 variant. 

 

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

  <PropertyGroup>
    <TargetFramework>net5.0-windows</TargetFramework>
    <UseWindowsForms>true</UseWindowsForms>
  </PropertyGroup>

  <ItemGroup>
    <Reference Include="PaintDotNet.Base">
      <HintPath>..\..\..\paint.net.portable\PaintDotNet.Base.dll</HintPath>
    </Reference>
    <Reference Include="PaintDotNet.Core">
      <HintPath>..\..\..\paint.net.portable\PaintDotNet.Core.dll</HintPath>
    </Reference>
    <Reference Include="PaintDotNet.Data">
      <HintPath>..\..\..\paint.net.portable\PaintDotNet.Data.dll</HintPath>
    </Reference>
  </ItemGroup>

</Project>

 

You have to adapt the paths to your paint.net 4.3 installation (absolute paths are ok) or remove them from the project file and add them again in the SolutionExplorer/dependencies/assemblies

In the properties of the project you may select Resources and add a new one if you like to add an icon.

  • Like 1

midoras signature.gif

Link to comment
Share on other sites

1 hour ago, MJW said:

I've installed new frameworks in the past, and though I don't recall the details, I don't remember it being especially difficult.

 

You have to convert the project file to the .NET 5 format before that targeting option becomes available.

 

1 hour ago, midora said:

Never detected a possibility in VS2019 to switch forth and back from 4.7.2 (and lower) to 5 (and upper).

 

Microsoft has a try-convert tool that updates a .NET Framework projects/solutions to the .NET 5 format, I have used it when converting my plugin projects to .NET 5.

  • Like 2
  • Upvote 1

PdnSig.png

Plugin Pack | PSFilterPdn | Content Aware Fill | G'MICPaint Shop Pro Filetype | RAW Filetype | WebP Filetype

The small increase in performance you get coding in C++ over C# is hardly enough to offset the headache of coding in the C++ language. ~BoltBait

 

Link to comment
Share on other sites

@MJW I've struggled with that issue for over a month. I've found the best way to tackle the issue is build the plugin initially in Codelab. You have the code so it should be easy enough for you. Now export the plugin to a VS solution that Codelab does very well at. In fact it's amazing how it builds the VS solution better than trying to update an old DLL through VS 2019. I've built over a dozen DLL's this way and found it to be the easiest. Once @toe_head2001 releases his templates, then you can start building with VS to start with again. Of course you could start from the beginning in VS which will allow you to use Net 5.0, build your plugin, then export it as a template for the next one.

I have found the syntax in try-convert to be quite unfriendly. @midora's suggestion appears to work to a certain extent, but depending on what your plugin is doing, it may create a headache once or twice.

PaintNetSignature.png.6bca4e07f5d738b2436f83d0ce1b876f.png

Link to comment
Share on other sites

14 minutes ago, AndrewDavid said:

I've found the best way to tackle the issue is build the plugin initially in Codelab.

 

These are already-existing Visual Studio projects which will likely have to be rebuilt at some point for improvements and perhaps bug fixes.

Link to comment
Share on other sites

7 hours ago, null54 said:

You have to convert the project file to the .NET 5 format before that targeting option becomes available.

 

Am I the only one who thinks if Microsoft requires such a thing to be done, they ought to add a conversion tool in an update to Visual Studio?

Link to comment
Share on other sites

46 minutes ago, MJW said:

Am I the only one who thinks if Microsoft requires such a thing to be done, they ought to add a conversion tool in an update to Visual Studio?

 

They are to busy to create tools to customize the colors in VisualStudio.

https://docs.microsoft.com/en-us/visualstudio/extensibility/ux-guidelines/color-value-reference-for-visual-studio?view=vs-2019

  • Haha 1

midoras signature.gif

Link to comment
Share on other sites

I tried try-convert, and though I'm sure it gave it the old college try, it failed. It hung after "Instance 10" (not sure what that means). I left it for about half an hour, in case it was just doing something lengthy, then exited with a Ctrl-C. Unsurprisingly, no 5.0 appeared in the Properties framework choices.

 

I find this all quite annoying.

Link to comment
Share on other sites

Yeah, that's odd.  Try-convert should take about a second to run.

Personally, I've never had any trouble with the tool, but I've only used it about five times.

 

In this case, I would just rewrite the .csproj file manually, midora originally suggested.

(September 25th, 2023)  Sorry about any broken images in my posts. I am aware of the issue.

bp-sig.png
My Gallery  |  My Plugin Pack

Layman's Guide to CodeLab

Link to comment
Share on other sites

18 hours ago, MJW said:

I tried to build an existing plugin now that I've installed the new version of PDN that uses .NET 5.0. Naturally, I got the usual slew of errors that comes from building using a version of PDN that's different from the framework for the plugin project. I opened the project's Properties to change the target framework, but 5.0 was not among the choices. From the list, I selected "Install other frameworks" which semi-helpfully took me to a webpage of SDK and runtime downloads. Just to be safe, I installed all the 5.0 stuff. I again tried selecting 5.0 from the framework list, but it still wasn't there. I restarted Visual Studio, which didn't help. I was able to build a console app that used 5.0, so 5.0 must be installed.

 

 

^ This is my situation too. I've recently tried upgrading VS2019 and also repairing it. Neither of these restored the missing .NET 5.0 entry from the dropdown of available frameworks.

 

I'm thinking my next step is just to install VS2021 and see how that works.

Link to comment
Share on other sites

17 hours ago, null54 said:

You have to convert the project file to the .NET 5 format before that targeting option becomes available.

 

How does one do this?

Link to comment
Share on other sites

24 minutes ago, Ego Eram Reputo said:

How does one do this?

 

You can run try-convert on the project.

 

Or you can manually edit your .csproj file. Delete everything in the file, and then copy-paste the code midora posted. Save the file, and you're done.

(September 25th, 2023)  Sorry about any broken images in my posts. I am aware of the issue.

bp-sig.png
My Gallery  |  My Plugin Pack

Layman's Guide to CodeLab

Link to comment
Share on other sites

Thanks.

 

I'm wading through a swathe of warnings & a couple of error messages, but I've got a working plugin once again! Very pleased :mrgreen:

Link to comment
Share on other sites

42 minutes ago, toe_head2001 said:

Or you can manually edit your .csproj file. Delete everything in the file, and then copy-paste the code midora posted. Save the file, and you're done.

 

I'm a bit concerned, because my .csproj files have a lot more in them than what would seem like the equivalent lines, including many more links to Paint.NET component DLLs. Does midora's code replace the whole file, or only a section of it?

 

An example of my .cproj file:

Spoiler
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>8.0.50727</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{DE5994B9-1CBC-4D0D-8006-F70BB0DB77F2}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>Test_5._0_Plugin</RootNamespace>
    <AssemblyName>Test 5.0 Plugin</AssemblyName>
    <StartupObject>
    </StartupObject>
    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
    <FileUpgradeFlags>
    </FileUpgradeFlags>
    <OldToolsVersion>2.0</OldToolsVersion>
    <UpgradeBackupLocation />
    <PublishUrl>publish\</PublishUrl>
    <Install>true</Install>
    <InstallFrom>Disk</InstallFrom>
    <UpdateEnabled>false</UpdateEnabled>
    <UpdateMode>Foreground</UpdateMode>
    <UpdateInterval>7</UpdateInterval>
    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
    <UpdatePeriodically>false</UpdatePeriodically>
    <UpdateRequired>false</UpdateRequired>
    <MapFileExtensions>true</MapFileExtensions>
    <ApplicationRevision>0</ApplicationRevision>
    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
    <IsWebBootstrapper>false</IsWebBootstrapper>
    <UseApplicationTrust>false</UseApplicationTrust>
    <BootstrapperEnabled>true</BootstrapperEnabled>
    <TargetFrameworkProfile />
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>TRACE;DEBUG;VISUALSTUDIO</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
    <Prefer32Bit>false</Prefer32Bit>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE;VISUALSTUDIO</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
    <Prefer32Bit>false</Prefer32Bit>
    <RunCodeAnalysis>true</RunCodeAnalysis>
  </PropertyGroup>
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
  <ItemGroup>
    <Reference Include="PaintDotNet">
      <HintPath>..\..\..\..\..\..\..\Program Files\Paint.NET\PaintDotNet.exe</HintPath>
    </Reference>
    <Reference Include="PaintDotNet.Base">
      <HintPath>..\..\..\..\..\..\..\Program Files\Paint.NET\PaintDotNet.Base.dll</HintPath>
    </Reference>
    <Reference Include="PaintDotNet.Core">
      <HintPath>..\..\..\..\..\..\..\Program Files\Paint.NET\PaintDotNet.Core.dll</HintPath>
    </Reference>
    <Reference Include="PaintDotNet.Data">
      <HintPath>..\..\..\..\..\..\..\Program Files\Paint.NET\PaintDotNet.Data.dll</HintPath>
    </Reference>
    <Reference Include="PaintDotNet.Effects, Version=3.0.2477.19862, Culture=neutral, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>..\..\..\..\..\..\..\Program Files\Paint.NET\PaintDotNet.Effects.dll</HintPath>
    </Reference>
    <Reference Include="PaintDotNet.Framework, Version=4.6.5693.28, Culture=neutral, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>..\..\..\..\..\..\..\Program Files\paint.net\PaintDotNet.Framework.dll</HintPath>
    </Reference>
    <Reference Include="PaintDotNet.Resources, Version=4.6.5693.28, Culture=neutral, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>..\..\..\..\..\..\..\Program Files\paint.net\PaintDotNet.Resources.dll</HintPath>
    </Reference>
    <Reference Include="PaintDotNet.SystemLayer, Version=4.6.5693.28, Culture=neutral, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>..\..\..\..\..\..\..\Program Files\paint.net\PaintDotNet.SystemLayer.dll</HintPath>
    </Reference>
    <Reference Include="PaintDotNet.SystemLayer.Native.x64, Version=4.6.5693.28, Culture=neutral, processorArchitecture=AMD64">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>..\..\..\..\..\..\..\Program Files\paint.net\PaintDotNet.SystemLayer.Native.x64.dll</HintPath>
    </Reference>
    <Reference Include="PaintDotNet.SystemLayer.Native.x86, Version=4.6.5693.28, Culture=neutral, processorArchitecture=x86">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>..\..\..\..\..\..\..\Program Files\paint.net\PaintDotNet.SystemLayer.Native.x86.dll</HintPath>
    </Reference>
    <Reference Include="PdnRepair">
      <HintPath>..\..\..\..\..\..\..\Program Files\paint.net\PdnRepair.exe</HintPath>
    </Reference>
    <Reference Include="System" />
    <Reference Include="System.Drawing" />
    <Reference Include="System.IO.Compression" />
    <Reference Include="System.Windows.Forms" />
    <Reference Include="WindowsBase" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="..\..\UtensilsPDN\HelpMenuRtf.cs">
      <Link>HelpMenuRtf.cs</Link>
    </Compile>
    <Compile Include="..\..\UtensilsPDN\IndirectUIControlsEZ.cs">
      <Link>IndirectUIControlsEZ.cs</Link>
    </Compile>
    <Compile Include="..\..\UtensilsPDN\PropertyBasedEffectEZ.cs">
      <Link>PropertyBasedEffectEZ.cs</Link>
    </Compile>
    <Compile Include="Properties\Resources.Designer.cs">
      <DependentUpon>Resources.resx</DependentUpon>
      <DesignTime>True</DesignTime>
      <AutoGen>True</AutoGen>
    </Compile>
    <Compile Include="Resources\Resource1.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>Resource1.resx</DependentUpon>
    </Compile>
    <Compile Include="Test_5._0_Plugin.cs" />
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="Properties\Resources.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
    </EmbeddedResource>
    <EmbeddedResource Include="Resources\Resource1.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resource1.Designer.cs</LastGenOutput>
    </EmbeddedResource>
  </ItemGroup>
  <ItemGroup>
    <BootstrapperPackage Include=".NETFramework,Version=v4.0">
      <Visible>False</Visible>
      <ProductName>Microsoft .NET Framework 4 %28x86 and x64%29</ProductName>
      <Install>true</Install>
    </BootstrapperPackage>
    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
      <Visible>False</Visible>
      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
      <Install>false</Install>
    </BootstrapperPackage>
    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
      <Visible>False</Visible>
      <ProductName>.NET Framework 3.5 SP1</ProductName>
      <Install>false</Install>
    </BootstrapperPackage>
    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
      <Visible>False</Visible>
      <ProductName>Windows Installer 3.1</ProductName>
      <Install>true</Install>
    </BootstrapperPackage>
  </ItemGroup>
  <ItemGroup>
    <None Include="Resources\Help.rtf" />
    <None Include="Resources\Icon.png" />
  </ItemGroup>
  <ItemGroup>
    <WCFMetadata Include="Service References\" />
  </ItemGroup>
  <PropertyGroup>
    <PostBuildEvent>copy  /y   "$(TargetFileName)" "C:\Program Files\Paint.NET\Effects"</PostBuildEvent>
  </PropertyGroup>
</Project>

 

 

Link to comment
Share on other sites

Keep a copy if you're worried. I did.

 

I removed everything except the post-build-event. When that gave me an error I removed that too.

Link to comment
Share on other sites

19 minutes ago, MJW said:

Does midora's code replace the whole file, or only a section of it?

 

It replaces the whole file.  Seriously.

 

The newer .NET Sdk format for .csproj files is much simpler, and it's smart enough to use proper settings by default.

(September 25th, 2023)  Sorry about any broken images in my posts. I am aware of the issue.

bp-sig.png
My Gallery  |  My Plugin Pack

Layman's Guide to CodeLab

Link to comment
Share on other sites

The new variant of the project file doesn't contain references to the files contained in the project folder. That's the main reason why the old one is much larger.

 

My snippet doesn't contain references to all paint.net dlls. So you have to add the ones missing in your project (manually by editing the file or via right click to SolutionExplorer/dependencies).

 

You should try to resolve all warnings (beside of this WindowsBase version conflict).

 

midoras signature.gif

Link to comment
Share on other sites

The 5.0 .csproj file that resulted from running the Upgrade Assistant app is fairly similar to the original .csproj file in content and size. Likely that's because it modified the original file rather than building one from scratch. I'll try to experiment with the smaller replacement .csproj file tomorrow.

Link to comment
Share on other sites

How I converted all my effects for NET 5.0:

 

1. Run CodeLab 6.3
2. In the default script in the comment // Name: type the name of your plugin (f.e. MyEffect).
3. Save the script with this name.
4. Then File -> Build DLL -> Generate VS Solution.
5. Open MyEffect solution in VS 2019, then open MyEffect.cs.
6. Open your old MyEffect.cs in any text editor.
7. Move all the code blocks from the text editor sequentially to the new MyEffect.cs.
8. Delete unused references and dependencies. If necessary, fix the errors.
9. Your new project is ready.

 

For me, this algorithm seemed to be the simplest solution for converting old projects into new ones. It takes a little time and requires minimal effort to fix old scripts.

For many of my effects, it would be enough to build an effect in CodeLab, but all my effects have a UI in two languages, so I use VS.

Link to comment
Share on other sites

On 10/16/2021 at 2:20 AM, MJW said:

I'll try to experiment with the smaller replacement .csproj file tomorrow.


I got the 5.0 build to (mostly) work using midora's .csproj file without too many changes.

 

Besides some path changes to match the location of my PDN folder, I had to add  PaintDotNet.Effects.dll to the list of PDN references.

 

Perhaps it's my particular way of building, but I also had to set GenerateAssmblyInfo to false in the first PropertyGroup section:

  <PropertyGroup>
    <TargetFramework>net5.0-windows</TargetFramework>
    <UseWindowsForms>true</UseWindowsForms>
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
  </PropertyGroup>

 

Without doing that, VS auto-generates a file containing copies of the Assembly properties, such as the plugin name, which results in multiple references.

 

I also had to enable unsafe blocks:

  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DefineConstants>TRACE;DEBUG;VISUALSTUDIO</DefineConstants>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DefineConstants>TRACE;VISUALSTUDIO</DefineConstants>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
  </PropertyGroup>

 

The one annoying problem I haven't solved is for the post-build event that copies the DLL to the Effects folder:

  <PropertyGroup>
    <PostBuildEvent>copy /y "$(TargetPath)" "C:\Program Files\Paint.NET\Effects"</PostBuildEvent>
  </PropertyGroup>

 

It's always worked in the past, but now the $(TargetPath) macro doesn't seem to get expanded. I get no copying of the DLL, and the error:

The command "copy  /y  "" "C:\Program Files\Paint.NET\Effects"" exited with code 1.

 

$(TargetPath) should expand to the complete path for the Release or Debug DLL, depending on which is built.

 

(In other pre-5.0 .csproj files I have $(TargetFile) instead of $(TargetPath). $(TargetFile) is just the bare DLL filename. When that didn't work -- for the same reason -- I thought I'd try giving the copy command the full path.)

 

EDIT: null54 has the solution to my problem in the comment that follows.

Link to comment
Share on other sites

34 minutes ago, MJW said:

The one annoying problem I haven't solved is for the post-build event that copies the DLL to the Effects folder:

 

The .NET 5 projects have a new post build event property.

Replace your existing post build event with the following:

 

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
    <Exec Command="copy &quot;$(TargetPath)&quot; &quot;C:\Program Files\paint.net\Effects&quot; /y" />
</Target>

 

  • Like 1

PdnSig.png

Plugin Pack | PSFilterPdn | Content Aware Fill | G'MICPaint Shop Pro Filetype | RAW Filetype | WebP Filetype

The small increase in performance you get coding in C++ over C# is hardly enough to offset the headache of coding in the C++ language. ~BoltBait

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...