Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NET 5 cannot produce console app with visible window if it references Windows Forms #14503

Closed
kaby76 opened this issue Nov 11, 2020 · 20 comments
Closed
Assignees
Labels
untriaged Request triage from a team member

Comments

@kaby76
Copy link

kaby76 commented Nov 11, 2020

I have the following code:

consoleapp.csproj

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <UseWPF>true</UseWPF>
    <UseWindowsForms>true</UseWindowsForms>
  </PropertyGroup>

</Project>

Program.cs

using System;
using System.Windows.Forms;

namespace consoleapp
{
	class Program
	{
		static void Main(string[] args)
		{
			Console.WriteLine("Hello World!");
			for (;;)
			{
				var input = Console.ReadLine();
				System.Console.WriteLine("Got " + input);
				if (input == "form")
				{
					Form frm = new Form();
					Button btn = new Button()
					{
						Left = 120,
						Width = 130,
						Height = 30,
						Top = 150,
						Text = "OK"
					};
					frm.Controls.Add(btn);
					frm.ShowDialog();
				}
			}
		}
	}
}

Under Net Core 3.1.302, dotnet build produces an .exe that when double-clicked in Windows Explorer, starts the app with a visible window.

Under Net 5.0.100, dotnet build produces an .exe that when double-clicked in Windows Explorer, starts the application but there is no visible window.

In the documentation, it notes "* Starting in .NET 5.0, Windows Forms and Windows Presentation Foundation (WPF) projects should specify the .NET SDK (Microsoft.NET.Sdk) instead of Microsoft.NET.Sdk.WindowsDesktop. For these projects, setting TargetFramework to net5.0-windows and UseWPF or UseWindowsForms to true will automatically import the Windows desktop SDK. If your project targets .NET 5.0 or later and specifies the Microsoft.NET.Sdk.WindowsDesktop SDK, you'll get build warning NETSDK1137." Following those instructions--and many permutations with/without .WindowsDesktop, TargetFramework, UseWPF, UseWindowsForms--there is nothing that I can do to produce a console app that, when double-clicking on the .exe, has a visible window for NET 5.

This is a problem because when the .csproj is opened in VS2019.8 and the program debugged via F5, there is no window. (It is actually worse in my application because a Read() from stdin return EOF=-1, just because there really is no visible/attacted window for a CLI prompt. I could start the program in a cmd.exe terminal, then attach the debugger to my program, but this is a royal pain, and I have to insert Sleep() calls at the start of the program if I want to debug start up code.) If I click on Properties for "consoleapp" in the Solution Explorer in VS2019.8, the "Output type" is "Windows Application", I change the "Output type" to "Console Application", then save. After closing and reopening, I re-display the the properties for the program--it's stuck at "Windows Application".

This is a console application that requires a window because it's a CLI program. On some commands, it will pop open a Windows Form. I can start the program in a console window, but I cannot debug the program startup because there is no visible window.

The actual use case is my program Trash, a Bash-like shell but for parsing, parse trees, grammar refactorings, compiler development, where I want a console application that can occasionally display decorated parse trees using Automatic Graph Layout. For the moment, the AGL display is in-process, but I may move to an out-of-process command set if I can pass huge trees between processes with fast IPC. But I am not hopeful because parse trees are frigging huge.

Is there a way of setting up the csproj file--or elsewhere--so that I get a visible window? Why does VS2019.8 think this is a Windows Application? Does the Output set to "Exe" mean anything? Why does VS2019.8 application settings for Console Application not stick?

(As I note in a follow-up comment, setting up a global.json file for 3.1.302 is a workaround. However, I'd like to move forward to NET 5.)

--Ken Domino

@kaby76
Copy link
Author

kaby76 commented Nov 11, 2020

After many permutations, I found out that one can install the NET 5.0.100 SDK, but use the older NET Core 3.1.302 SDK by including a global.json to make sure that is used.

{
  "sdk": {
    "version": "3.1.302"
  }
}

I placed this file in ~/Documents/, and that seemed to work.

@kaby76 kaby76 closed this as completed Nov 11, 2020
@kaby76 kaby76 reopened this Nov 11, 2020
@rbqm
Copy link

rbqm commented Nov 17, 2020

I'm using the following workaround for debugging:

  • Open property page of the project
  • Go to Debug tab
  • Set "Launch" to "Executable"
  • Set "Executable" to "dotnet.exe"
  • Set "Application arguments" to "name of your project.dll"

Hopefully this workaround will not be needed anymore in Visual Studio 16.9

@kaby76
Copy link
Author

kaby76 commented Nov 17, 2020

@rbqm Thank you! That works.

@DrPepperBianco
Copy link

DrPepperBianco commented Nov 19, 2020

I have the same problem. <OutputType> is "Exe" and <UseWindowsForms> is "true". Generated exe file is "WinExe" instead (I assume) and doesn't show Console output.

The error seems to only happen, if I use the new Core-Style project files. I just created a new framework project (with old-style project) it seems to work correctly.

But I already updated most of our active projects to new Core-Style project files (even though I haven't updated target framework to core, because of external dependencies).

@DrPepperBianco
Copy link

DrPepperBianco commented Nov 19, 2020

After many permutations, I found out that one can install the NET 5.0.100 SDK, but use the older NET Core 3.1.302 SDK by including a global.json to make sure that is used.

{
  "sdk": {
    "version": "3.1.302"
  }
}

That worked for me, but only from a console, not from Visual Studio. But it's still good, because without it the programm cannot be build as Console anymore.

The workaround with launching via 'dotnet' and 'project.dll' didn't work, because TargetFramework is net471 and this only works for Core.

@DrPepperBianco
Copy link

OK, here is another workaround, but this probably only applies for Application targeting .net Framework.

I set <UseWindowsForms> to "false". Instead I just added <Reference Include="System.Windows.Forms" /> (to reference the dependencies directly). After that application could be compiled correctly in both console and Visual Studio. I also this workaround doesn't depend on global.json.

@mkvonarx
Copy link

This looks to be intentional. See https://docs.microsoft.com/en-us/dotnet/core/compatibility/windows-forms/5.0/automatically-infer-winexe-output-type

To revert to the old behavior, you can set this property in the .csproj file:

<DisableWinExeOutputInference>true</DisableWinExeOutputInference>

@NikolaosWakem
Copy link

NikolaosWakem commented Mar 1, 2021

"Reason for change" : Break production 3.1 apps and waste peoples time - ticking time bomb for loads of people the next time they rebuild their 3.1 app on DevOps. (like I did today)

@Manuzor
Copy link

Manuzor commented May 5, 2021

If I explicitly set <OutputType> I want it to respect that. Instead it just ignores it silently with no feedback whatsoever. I don't see why this should be the default behavior at all.

If for whatever reason this behavior has to stay, it could at least issue a warning saying something like this:

<OutputType>Exe</OutputType> detected in your .csproj file will be ignored. Please change the OutputType to WinExe or add <DisableWinExeOutputInference>true</DisableWinExeOutputInference> to revert to the expected behavior. See https://docs.microsoft.com/en-us/dotnet/core/compatibility/windows-forms/5.0/automatically-infer-winexe-output-type

@ChahatKumar
Copy link

ChahatKumar commented May 17, 2021

@kaby76 I was making a console app( .NET CORE 5 ) and tried referencing windows.forms In it and modified the cs.proj to this

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <UseWPF>true</UseWPF>
    <UseWindowsForms>true</UseWindowsForms>
  </PropertyGroup>

</Project>

`

But only the form and no console is shown ?
Its necessarily transforming into a Winform ?

Did you find a way to show both console and form using dontnet 5 console app?

@Manuzor
Copy link

Manuzor commented May 18, 2021

@ChahatKumar You need to add the following to your csproj file:

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <UseWPF>true</UseWPF>
    <UseWindowsForms>true</UseWindowsForms>
    <DisableWinExeOutputInference>true</DisableWinExeOutputInference> <!--  Add this line  -->
  </PropertyGroup>

</Project>

Otherwise <UseWindowsForms>true</UseWindowsForms> and <UseWPF>true</UseWPF> will override your OutputType to WinExe.

This is precisely the point of my comment earlier. Without a warning of some kind for the csproj above, users like myself and @ChahatKumar will have no way of knowing that they will get something else than what they expect.

@ChahatKumar
Copy link

@Manuzor Okay Thanks a lot !
I can see the form and console but they just appear while I run my app. ( I have defined form class separately and calling from my main function) .
Is there a work-around for the form to pop up while I build the Project solution ?

@Manuzor
Copy link

Manuzor commented May 18, 2021

You are trying to open a Form instance while the project is building? So in other words, trying to run your code before it is compiled? That obviously doesn't work. I don't think I understand what you're trying to achieve, but it sounds unrelated to this issue.

@ChahatKumar
Copy link

I just wanted a way to show a pop-up or any tool to show the user a message and collect info during build time .
Yes apologies it isn't related to this issue in particular .

@marcpopMSFT marcpopMSFT added the untriaged Request triage from a team member label May 25, 2021
@BittermanAndy
Copy link

BittermanAndy commented Aug 17, 2021

Given that the upgrade-assistant tool provided by Microsoft seems to set all projects to <UseWindowsForms> by default, this is unbelievably obnoxious.

I've just wasted an hour of my life trying to work out why a console application doesn't show the console, and can't call Console.WriteLine without crashing, before finally stumbling across this.

Please, please stop torturing us. Please think for at least five seconds before breaking something like this.

@KalleOlaviNiemitalo
Copy link
Contributor

This has already been fixed so that .NET 6 SDK no longer changes OutputType to WinExe in Windows Forms projects. See #16563 and dotnet/docs#25636.

Is this issue now a duplicate of #16563 or is this a request to make the same change to .NET 5 SDK as well?

@BittermanAndy
Copy link

I mean, it ought to do the same for .NET 5 because it should never have behaved this stupidly in the first place... so sure, please go ahead and fix it in .NET 5.

Bit late for me though, as I'm doing the update to .NET 5 today, because that's the current release (.NET 6 still in preview).

(You'll have to pardon me if I'm a bit snarky. I've got 173 projects to upgrade to .NET instead of Framework, and it's the most painful experience I've had in 19 years as a software developer because of nonsense like this).

@cjsio
Copy link

cjsio commented Nov 2, 2022

Found this thread because of a closely-coupled issue.

Can't compile my .NET 5 class library into .dll.

Adding <UseWindowsForms>true</UseWindowsForms> to my .csproj file with a target of either net5.0-windows or net6.0-windows acts as if Visual Studio compiled it into a dll (according to the Output pane), but the dll is not updated in the BaseOutputPath directory unless <UseWindowsForms>true</UseWindowsForms> is removed from the .csproj file. But I need this reference to access some .Forms objects:

Inside one of the library's classes I define an OpenFileDialog instance. My understanding is that because I've defined the target framework version with the -windows suffix, along with the <UseWindowsForms>true</UseWindowsForms> setting, that I should have no issue declaring this instance nor accessing DialogResult instances all the same.

I also read that <Project Sdk="Microsoft.NET.Sdk"> should say <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">, but in the original report, OP states this should be deprecated according to the linked documentation:

In the documentation, it notes "* Starting in .NET 5.0, Windows Forms and Windows Presentation Foundation (WPF) projects should specify the .NET SDK (Microsoft.NET.Sdk) instead of Microsoft.NET.Sdk.WindowsDesktop. For these projects, setting TargetFramework to net5.0-windows and UseWPF or UseWindowsForms to true will automatically import the Windows desktop SDK. If your project targets .NET 5.0 or later and specifies the Microsoft.NET.Sdk.WindowsDesktop SDK, you'll get build warning NETSDK1137." Following those instructions--and many permutations with/without .WindowsDesktop, TargetFramework, UseWPF, UseWindowsForms--there is nothing that I can do to produce a console app that, when double-clicking on the .exe, has a visible window for NET 5.

I also found suggestions to add <DisableWinExeOutputInference>true</DisableWinExeOutputInference> but this setting appears to be deprecated as well, at least as of .NET 6.

Lastly I tried explicitly setting <OutputType>Library</OutputType>, but not this nor a value of Exe nor WinExe allows me to build the dll whether or not I have the <DisableWinExeOutputInference> value set to true.

In .NET 5/6, how do we hook into the windows-only .Forms objects and still have the class library .dll build? Thanks

@marcpopMSFT
Copy link
Member

Old bug triage: Looks like folks determined the workaround of using DisableWinExeOutputInference so closing this issue out.

@marcpopMSFT marcpopMSFT closed this as not planned Won't fix, can't repro, duplicate, stale May 30, 2023
@cjsio
Copy link

cjsio commented May 30, 2023

Old bug triage: Looks like folks determined the workaround of using DisableWinExeOutputInference so closing this issue out.

Please see my response. DisableWinExeOutputInference does not solve the issue. This should not be prematurely closed out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
untriaged Request triage from a team member
Projects
None yet
Development

No branches or pull requests