Laden...

Konsole+Windows Forms in .NET 5

Erstellt von Tommix vor 2 Jahren Letzter Beitrag vor 2 Jahren 3.236 Views
T
Tommix Themenstarter:in
9 Beiträge seit 2021
vor 2 Jahren
Konsole+Windows Forms in .NET 5

Hallo,
obwohl das Thema nach Windows Forms klingt wird es wohl bei WPF nicht anders sein, drum poste ich hier. Folgendes Szenario: Ich habe (hier als möglichst simples Beispiel) ein Konsolen-Programm, welches Windows Forms nutzt:


using System;
using System.Windows.Forms;

namespace Test
{
    class HelloWorld
    {
        static void Main()
        {
            Console.WriteLine("Hello world!");
            MessageBox.Show("Hello world!");
        }
    }
}

Unter .Net 4.x und vorher hat man einen Verweis auf System.Windows.Forms hinzugefügt und gut war. Unter .Net core musste ich die Projektdatei ändern:


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

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

Soweit, so gut. Jetzt will ich das Gleiche mit .Net 5 machen.


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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
    <UseWindowsForms>true</UseWindowsForms>
  </PropertyGroup>
</Project>

Führt zu> Fehlermeldung:

error NETSDK1136: Die Zielplattform muss auf Windows festgelegt werden (üblicherweise durch Einbeziehen von "-windows" in die TargetFramework-Eigenschaft), wenn Windows Forms oder WPF verwendet wird oder auf Projekte oder Pakete verwiesen wird, die dies tun.

Also:


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

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

Jetzt läuft es zwar, die MessageBox erscheint, aber ich bekomme keine Ausgabe auf der Konsole. Im Debugger geht gar kein Konsolenfenster auf und wenn ich es aus der Kommandozeile starte, fehlt die Ausgabe. Das es bei Target Windows-Anwendung keine Konsole gibt, war schon immer so. Aber ich will ja nun gerade eine Konsolen-Anwendung haben und nur auf die Klassen aus Windows-Forms zugreifen. Wenn ich google lande ich immer nut bei dem Tip mit dem UseWindowsForms aber vielleicht formuliere ich die Frage auch falsch. Bin für jeden Denkanstoß dankbar.

Gruss Tommix

16.807 Beiträge seit 2008
vor 2 Jahren

Kannst Du evtl. auch erklären, was Dein eigentlichen Ziel ist, warum Du eine Konsolen-Anwendung mit Forms / WPF machen willst?

UseWindowsForms bzw. das Pendant UseWPF ist ein Compiler Feature und keine Referenz.
Das bedeutet, dass die Anwendung selbst Richtung WinForms/WPF ausgerichtet ist. Daher ändert sich natürlich auch der Default Output, weshalb Deine Konsole leer bleibt.

Wenn Du in einer Console App Dinge aus Forms/WPF verwenden willst, dann musst Du mit Referenzen arbeiten, i.d.R. via NuGet.
Das gilt aber nicht für die Anzeige selbst: Eine Message Box bzw. Fenster kannst Du aus einer Console App aber niemals öffnen. Eine Console App hat keinen UI Zugriff, was aber nicht an .NET liegt sondern wie Betriebssysteme funktionieren.

Ich hab irgendwie das Gefühl, dass Du insgesamt viel vermischt.
Daher bitte erste Frage beantworten, damit man versteht, was Dein eigentliches Ziel ist.

D
152 Beiträge seit 2013
vor 2 Jahren

Du willst eine Konsolen Anwendung und darin WinForms verwenden?

Siehe dir mal Konsolenfenster und Windows-Fenster in einer .NET-5.0-App und OutputType für WPF- und WinForms-Apps auf WinExe festgelegt an.


<DisableWinExeOutputInference>true</DisableWinExeOutputInference>

T
Tommix Themenstarter:in
9 Beiträge seit 2021
vor 2 Jahren

Hallo Abt,
ich habe ein paar Hausgebrauchs-Tools, die das Resultat per System.Windows.Forms.Clipboard.SetText in die Zwischenablage kopieren, damit ich es in Excel einfügen kann. Ich weiß, dass das nicht besonder elegant ist, aber für mich zum reinen Privatgebrauch ist es ok.

Eine Message Box bzw. Fenster kannst Du aus einer Console App aber niemals öffnen.

Da muss ich widersprechen, wie ich weiter oben postete, hat das bis .NET Core 3 noch funktioniert und in .NET 2-4 auch.
Allerdings hat der Post von david.m die Frage beantwortet, trotzdem Danke für die Zeit, die Du Dir genommen hast.

Gruss Tommix

Hallo David,
genau das hatte ich gesucht. Vielen Dank!

Tommix

16.807 Beiträge seit 2008
vor 2 Jahren

In einer "reinen Consolen App" geht das nicht; das geht nur über COM; i.d.R. via STAThread (Api-Docs).
Das gilt auch hier: willst Du auf das Clipboard über die Forms-Abhängigkeit zugreifen, musst Du die Konsolenanwendung als STAThread deklarieren (über die Main Methode).

In diesem Fall macht das UseWindowsForms unter der Haube.

T
Tommix Themenstarter:in
9 Beiträge seit 2021
vor 2 Jahren

Da hast Du recht. Ich hatte mein Beispiel zu weit reduziert, früher gab es bei dem fehlenden STAThreadAttribute eine Exception, da konnte man das nicht übersehen.

16.807 Beiträge seit 2008
vor 2 Jahren

Davon abgesehen, Du weißt, dass System.Windows.Forms.Clipboard.SetText nur ein Wrapper der Betriebssystem-Funktionalität ist?
Dahingehend gibt es auch viele Bibliotheken, die das wegabstrahieren.

zB GitHub - CopyText/TextCopy: A cross platform package to copy text to and from the clipboard.

T
Tommix Themenstarter:in
9 Beiträge seit 2021
vor 2 Jahren

Ja, klar. Und sicher nicht der Beste. Wenn ich mich recht entsinne (hab's mir mal mit ILSpy angeschaut) wird glaube ich zehn mal oder so der Kopiervorgang probiert bis bei Fehler eine Exception geworfen wird. Wenn ich ehrlich bin, war es auch eher die "Ich mach das jetzt seit 20 Jahren so, wieso geht das jetzt nicht mehr?"-Frage. Übrigens hier auch begründet: https://docs.microsoft.com/de-de/dotnet/core/compatibility/sdk/5.0/automatically-infer-winexe-output-type.

  • Tommix