Using dotnet CLI for Winforms with .NET 6 and .NET Framework 4.8
Tags: beginners, csharp, tutorial
Published: 2022-07-31 06:18:00


#Introduction
I have been interested in running some of my winforms based projects on CI services. However, preparing workflows for winforms application was cumbersome. It was primarily due to the fact that my projects uses .NET Framework 4.8. In order to be able to use CI service, we need to be able to build the solution or run test projects on the service. For example, Github Actions provide some templates for .NET (also assuming they work for .NET Core). The template does not work with .NET Framework based solutions. I was not able to find a good and easy solution for this. When I was analyzing the template on Github Action, it occured to me that I need to be able to use dotnet CLI first. The details of dotnet CLI can be found [here](https://docs.microsoft.com/en-us/dotnet/core/tools/).


##Using dotnet CLI for .NET Framework
Though dotnet CLI allows us to create a winform project and run it through command line, it is not as easy to run already created project with .net framework.
When we perform "dotnet run" in command line, we may see this kind of error.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fadzz2hrvojng8ua0xa8.png)
 
##Moving to .NET 6
The problem above can be resolved using .NET 6 instead of .NET Framework. Fortunately, .NET 6 supports winforms, so we can use it instead of .NET Framework. In this setting, `dotnet run` works and we can run the project.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7g8zghoxkj93h8dxvc6b.png)

This warning can be removed by changing <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop"> to <Project Sdk="Microsoft.NET.Sdk"> in the .proj file.

After changing the line, the warning disappeared.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ji8ef5b0pn4ep501elv.png)

##Using dotnet CLI with .NET Framework 4.8
Despite the fact we were not able to use `dotnet run` in a simple fasion, we can use the CLI if we modify the `.csproj` file.
If we have the same structure in the .proj file, we should be able to use the CLI since it supports both .NET 6 and .NET Framework.
I have tried the following by copying the structure of the .NET 6 `.csproj` file into .NET Framework `.csproj` file.

**.NET 6**
```xml
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net6.0-windows</TargetFramework>
    <UseWindowsForms>true</UseWindowsForms>
  </PropertyGroup>
</Project>
```
 
**.Net Framework 4.8**
```xml
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net48</TargetFramework>
    <UseWindowsForms>true</UseWindowsForms>
    <StartupObject>winformsCLI.Program</StartupObject>
  </PropertyGroup>
</Project>
```

After replacing the file, now we can use the CLI. The program runs without any problems, however, I am not entirely sure if this substitution is problematic or not.

##Adding unittest in the solution
We can now run the project using the CLI. It would be valuable if we are able to run the unittest as well. There is another obstacle when it comes to switching from .NET framework to .NET 6.
The winforms program shows the text `this is tofu` when the button is clicked. Tofu, being my cat.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8y1d46qalagsekcy899z.png)

We would like to write a test to check if the text is correct or not. The code for the winforms is the following.

```csharp
namespace WinformsCI
{
    public partial class Form1 : Form
    {
        private StringGen gen = new StringGen();
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            textBox1.Text = gen.GetString();
        }

    }

    public class StringGen
    {
        public string GetString()
        {
            return "this is tofu";
        }
    }
}
```

And here is the prepared test for it.
```csharp
  public class Tests
    {
        private StringGen gen;
        [SetUp]
        public void Setup()
        {
            gen = new StringGen();
        }

        [Test]
        public void Test1()
        {
            string result = gen.GetString();
            Assert.AreEqual("this is tofu", result);
        }
    }
```
Unfortunately, we cannot run this test because the winforms project relies on .NET 6-windows.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xd9pzz97lfo6bsydwlfl.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ml0ng8urb83y62hwk1g3.png)
 
The test project's target framework is .NET 6 and the OS is not specified. Therefore, we need to add specified the OS in the property.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/btnd79b7ydcbfd519jgz.png)

After doing it, we can run the test.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v6arpy64eg8120ssqcfi.png)

We should be able to use the CI services now and I would like to run the test using Github action next.