Porting Windows Forms to .Net Standard 2.0 - c#

Apologies if this is a very naive question. I wrote a Windows Form application using .Net 4.5 sometime ago. Recently, I thought it would be a good idea to port it to a .Net Standard 2.0 application using VS Code.
There were a couple of problems with missing libraries and classes (System.ServiceModel being the biggest gap), but I have got to the point of building the application successfully. However, when I come to run it, I see the following error:
Unhandled Exception: System.BadImageFormatException: Could not load file or assembly 'System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'. Reference assemblies should not be loaded for execution. They can only be loaded in the Reflection-only loader context. (Exception from HRESULT: 0x80131058) ---> System.BadImageFormatException: Cannot load a reference assembly for execution.
Here's the project file if it's useful:
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="log4net" Version="2.0.8" />
<PackageReference Include="Microsoft.CSharp" Version="4.4.0" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="NUnit" Version="3.8.1" />
<PackageReference Include="System.CodeDom" Version="4.4.0" />
<PackageReference Include="System.Configuration" Version="2.0.5" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.4.0" />
<PackageReference Include="System.Net.Http" Version="4.3.3" />
<PackageReference Include="System.ServiceModel" Version="1.0.0" />
<PackageReference Include="System.ServiceModel.Security" Version="4.4.0" />
<PackageReference Include="System.Windows.Forms" Version="4.0.0.0" />
</ItemGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
</Project>
Is there some way to run the application using the System.Windows.Forms library, or should I replace it with a different library for .Net Standard 2.0?

You cannot build an application that targets .NET Standard 2.0. Only libraries can target .NET Standard. Applications still have to target a specific runtime - .NET Framework, .NET Core, Xamarin, etc.
Judging by your project file, you're actually targeting .NET Core 2.0.
System.Windows.Forms is part of the .NET Framework (and Mono). It does not exist as part of .NET Standard or .NET Core.
Your project file has a PackageReference to System.Windows.Forms, which will pull in this NuGet package. It's unofficial and unlisted. Its very description is "unsupported library".
The DLL inside that package is only a reference assembly, i.e. none of the methods contain any actual code. That assembly only contains definitions.
This is what the error message means by "Reference assemblies should not be loaded for execution." The assembly in that package will let you compile, but nothing else.
There is no formal way to run a Windows Forms application on .NET Core (prior to 3.0). There may be a benefit to pulling our your business logic into a .NET Standard assembly, but your user interface will still have to be a .NET Framework application.

Related

Console App Updated to .Net Core 3.1 Error The framework 'Microsoft.AspNetCore.App', version '3.1.0' was not found

A quick preamble, I have seen a number of questions with this error already, but in all cases, these were users that were actually attempting to host asp.net core apps using the wrong container. That is not the case in my situation.
I have a working .net core console app hosted in a docker container that was targeting netcoreapp2.1 I started to update it to netcoreapp3.1 by changing the TargetFramework tag and updating the nuget packages. I also updated the base docker image (.net core runtime) from 2.1 to 3.1.
When I attempt to start this image I get the following error:
It was not possible to find any compatible framework version
The framework 'Microsoft.AspNetCore.App', version '3.1.0' was not found.
No frameworks were found.
You can resolve the problem by installing the specified framework and/or SDK.
The specified framework can be found at:
https://aka.ms/dotnet-core-applaunch?framework=Microsoft.AspNetCore.App&framework_version=3.1.0&arch=x64&rid=ubuntu.18.04-x64
The error message is correct that framework is not installed, but it should be looking for Microsoft.NetCore.App, which is installed in the container. It seems that is governed by The value of the Sdk attribute in the Project element in the csproj file which is <Project Sdk="Microsoft.NET.Sdk"> in this project.
What is causing the runtime to look for the wrong framework dependency?
The issue was a package reference to Serilog.AspNetCore The netstandard 2.0 version of the package is fine but the netcoreapp 3.1 version takes a framework refernce on Microsoft.AspNetCore.App:
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.1.1" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.2" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.2" />
</ItemGroup>
This dependency doesn't seem to be visible anywhere, which was why it was so difficult to track down. Removing the package, which didn't seem to actually be needed solved the problem.

Web Job: Library not found

We have a continuous WebJob that is written in .NET Core 2.x and has been running fine for the past few weeks. Recently someone made some changes to this WebJob and brought in a 3rd party NuGet package. Now, I am unable to start the WebJob because it is unable to locate one of the 3rd Party libraries dependencies.
This is the error message:
D:\local\Temp\jobs\continuous\Temp1\oitdncff.sfg>dotnet Temp1.dll
Error:
An assembly specified in the application dependencies manifest (Temp1.deps.json) was not found:
package: 'System.Drawing.Common', version: '4.5.0-preview1-25914-04'
path: 'runtimes/win/lib/netcoreapp2.0/System.Drawing.Common.dll'
I have tried several things I found whilst Googling this problem. Here is the PropertyGroup and ItemGroup (NuGet packages) from the csproj file:
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
<ApplicationIcon />
<StartupObject>Temp1.Program</StartupObject>
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<LangVersion>latest</LangVersion>
<Version>1.0.0.0</Version>
<PublishWithAspNetCoreTargetManifest>false</PublishWithAspNetCoreTargetManifest>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
<PackageReference Include="AsyncEnumerator" Version="2.1.0" />
<PackageReference Include="EPPlus.Core" Version="1.5.4" />
<PackageReference Include="Microsoft.ApplicationInsights" Version="2.5.1" />
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.5.1" />
<PackageReference Include="Microsoft.Azure.ServiceBus" Version="2.0.0" />
<PackageReference Include="Microsoft.Azure.WebJobs" Version="3.0.0-beta4" />
<PackageReference Include="Microsoft.Azure.WebJobs.Logging.ApplicationInsights" Version="3.0.0-beta4" />
<PackageReference Include="Microsoft.Azure.WebJobs.ServiceBus" Version="3.0.0-beta4" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Configuration" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
</ItemGroup>
Per suggestions online, I added the line
<PublishWithAspNetCoreTargetManifest>false</PublishWithAspNetCoreTargetManifest>
and
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
The package in question that has the dependency is EPPlus.Core
I have confirmed that the library System.Drawing.Common does exist in the app folder on our Azure Web App but the when the WebJob starts up, it is ignoring that the file is there and looking in the runtimes (GAC) and failing.
UPDATE:
I realized that the EPPlus.core package was not official so switched over to the official package hoping this would resolve the error. Same error but a new version of the System.Drawing.Common version: 4.5.0-preview1-26216-02
I have manually added the NuGet package for System.Drawing.Common version: 4.5.0-preview2-26406-04 to the project, this removed the original error but then I started getting an error that Microsoft.Win32.SystemEvents version: 4.5.0-preview2-26406-04 could not be found. This library is a dependent of System.Drawing.Common.
I attempted to do the same thing I did above and added the NuGet package for Microsoft.Win32.SystemEvents version: 4.5.0-preview2-26406-04 directly to the project but this time the error is not going away.
FURTHER UPDATE:
After searching more, I came across a posting here that talked about publishing and then zipping up the published directory and uploading the zip. This did actually work, the error in question was gone but this is not really a solution. We are using VSTS as our repo system and our CI/CD. I have the build configration set to do a publish and then copy the files up. The WebJob throws the error when its deployed via this process.
First, I would like to state that as of today, to my knowledge, .NET Core is not 100% supported with Azure WebJobs (feel free to correct me if I am wrong) but there are lots of articles and posts on how to make them work.
Below is the solution I did to get around the above issue I was having and whilst I do not feel this is elegant, I do feel that Microsoft has done something odd that most developers would not think is the correct path.
The reason I was having issues was that when I built (in debug or release) the manifest file was always pointing to the runtimes (GAC). Running locally on my box was never an issue because the files could be found. The oddity is when building in release mode, all files were copied to the bin folder yet the manifest still told the program to look in the runtimes and not to use the local copies. When this was pushed out to the WebJob itself, these files did not exist in the runtime so the WebJob would throw exceptions.
The workaround I had to do is as follows:
dotnet build (Solution - Release Configuration)
dotnet publish (WebJobs Only - Do Not Zip)
dotnet publish (Web Project Only - Do Not Zip)
Copy WebJob Data from Publish to the Web Project directory \App_Data\jobs\continuous\ directory
Zip Up Web Project Published Directory (this is what gets deployed)
My honest opinion is, when I build a webjob project in release mode, the process should transform the manifest to look for any referenced libraries locally before attempting to look for them in the runtimes.

System.Data.SqlClient is not supported on this platform

I'm using ASP.NET Core 2 with Entity Framework Core 2.0.2. I created a context and Add-Migrations command in Package Manager Controller works fine.
However when Update-Database command is used, I get an error:
System.Data.SqlClient is not supported on this platform
I can't figure out where the problem is. Can you help me? Thanks.
My .csproj file:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<DebugType>portable</DebugType>
<PreserveCompilationContext>true</PreserveCompilationContext>
<DockerComposeProjectPath>..\docker-compose.dcproj</DockerComposeProjectPath>
</PropertyGroup>
<ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.2.1" />
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.2" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="2.3.0" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.2" />
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.2" />
</ItemGroup>
</Project>
I ran into the same issue a couple of days ago - I'm not sure what the underlying issue is, but reverting some of the EntityFrameworkCore nuget packages back to 2.0.0 seems to have resolved the issue for me. These are the packages I downgraded:
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.0" />
Same problem here but for me it is a failure on the part of System.Data.SqlClient to load dynamically as part of a plugin. Our plugin dlls are loaded dynamically via Autofac and a controlling service selects the correct one at run time. Unfortunately System.Data.SqlClient will not load dynamically like this, result in the above error message. So I had to load it when the controlling service starts up. This is obviously not ideal but for now it is a usable workaround as all our plugins are still under our control.
I'll be more specific, following a question in comments.
A service selects plug-ins at run time. The plug-ins register their own dependencies via Autofac and if that dependency is a Nuget package they will also include the package as a normal Nuget dependency.
The controlling service registers the plug-in dlls on start up and the first time they are used the plug-in dependencies are also loaded. When System.Data.SqlClient load is attempted following a call to the plug-in that uses SqlClient the "not supported" error results.
Setting System.Data.SqlClient as a Nuget dependency in the controlling service works OK and the library is loaded correctly without error. However, this is not ideal because the the SqlClient library always has to be loaded by the controlling service even if the plug-in selected to run it does not need it.
In other words the SqlClient library is always loaded at service start up occupying resources, etc when it may not even be needed. But at least it works.
I ran into this issue recently with .net standard 2.0 classes being consumed by a regular .net framework app. (.net 4.7.x). The only thing that ultimately fixed my issue was migrating from packages.config to PackageReference on the regular .net app.
Just in case somebody lands here who is trying to run System.Data.SqlClient on net50/netstandard on rid freebsd-x64: Microsoft.Data.SqlClient worked for me.
Maybe this works on every portable option and/or for all System.[...] ->Microsoft.[...] dll.
I spent a couple of hours on this but managed to resolve it. Posting here in case it helps someone else save some time.
In my .csproj files I had
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
Removing this solved my problem. Some information can be found here. Setting the value to true causes all dependencies to be copied to the output folder and for me, maybe when loading the application, it was getting confused about which System.Data.SqlClient.dll to load.
I had this exact same issue with a .NET 5.0 console application i was deploying. I discovered that when i published the application the publish profiles target framework was set to 3.1 instead of 5.0 and that is what caused this error for me. After re-publishing with the correct target framework everything worked as expected.
String connectionString, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabaseImpl(String targetMigration, String connectionString, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_0.<.ctor>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Microsoft.Data.SqlClient is not supported on this platform."
go to manage nugget packages and do a downgrade. Hope it works for you
Change the framework to .NetCore 3.x or .NetFramework 4.x...

Building .net standard application that references Xamarin.Forms

I am trying to port a Windows.Forms application to .Net Standard 2.0 using Visual Studio Code. Based on responses to an earlier question (thank you guys), my plan is to try to use Xamarin.Forms to replace System.Windows.Forms. So, I add the Xamarin.Forms package to my project. When I try to run dotnet build, then I see the following error:
C:\Users\<user>\.nuget\packages\xamarin.forms\2.4.0.38779\build\netstandard1.0\Xamarin.Forms.targets(51,3): error MSB4062: The "Xamarin.Forms.Build.Tasks.FixedCreateCSharpManifestResourceName" task could not be loaded from the assembly C:\Users\<user>\.nuget\packages\xamarin.forms\2.4.0.38779\build\netstandard1.0\Xamarin.Forms.Build.Tasks.dll. Could not load file or assembly 'Microsoft.Build.Utilities.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified. Confirm that the <UsingTask> declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask.
I have tried to add various other Microsoft.Build packages but nothing seems to work. Is there a way forward here? Here's my current csproj file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="log4net" Version="2.0.8" />
<PackageReference Include="Microsoft.Build" Version="15.3.409" />
<PackageReference Include="Microsoft.Build.Framework" Version="15.3.409" />
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="15.3.409" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="15.3.409" />
<PackageReference Include="NUnit" Version="3.8.1" />
<PackageReference Include="System.Configuration" Version="2.0.5" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.4.0" />
<PackageReference Include="System.ServiceModel" Version="1.0.0" />
<PackageReference Include="Xamarin.Forms" Version="2.4.0.38779" />
</ItemGroup>
</Project>
I think that I may be asking the same question as here: Where is the difference of dotnet build on cmd vs VS2017? but am not sure.
I'm working on a Xamarin.Forms application and I'm migrating my libraries from PCL to NetStandard.
It seems that you can build the project with MsBuild.exe (I used C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\MSBuild.exe).
I found it mentioned in this blog post: https://oren.codes/2017/04/23/using-xamarin-forms-with-net-standard-vs-2017-edition/
You will need to use MSBuild.exe to build this, either on Windows with a VS 2017 command prompt or a Mac with Visual Studio for Mac. You cannot use dotnet build for these projects types. dotnet build only supports .NET Standard, .NET Core and .NET Framework project types. It is not able to build the Xamarin projects and the custom tasks in Xamarin Forms have not yet been updated to support .NET Core.
An additional note: I had to delete AssemblyInfo.cs, otherwise MsBuild complained about duplicate properties.

ASP.NET Core (.net 4.7) project created with VS2017 does not work with Visual Studio Code

I've created a new ASP.NET Core Project from scratch with the React Template of Visual Studio 2017 using the full .NET Framework instead of .NET Core as I need to use Entity Framework 6.
The project works without a problem in VS2017 and I can also build and run it with dotnet run and dotnet build.
But when I open the project in Visual Studio Code I always get the following error:
The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. [Test]
I've tried adding the NETStandard.Library to my project but the problem still exists.
These are all my referenced packages:
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0" />
I'm kind of clueless since googling for my error only brings up results of people having build problems, but my project builds without any issues.
Anything else I can try to get this working?
EDIT: My only installed extension is the c# extension provided by Microsoft if that makes any difference.

Categories