Comment créer, exécuter et contrôler un winform à partir d'une application console ?
@Kenny selon msdn, il l'a toujours été.
Comment créer, exécuter et contrôler un winform à partir d'une application console ?
L'option la plus simple est de démarrer un projet Windows forms, puis de changer le type de sortie en Application Console. Vous pouvez également ajouter une référence à System.Windows.Forms.dll et commencer à coder :
using System.Windows.Forms;
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.Run(new Form()); // or whatever
}
L'élément important est le [STAThread]
sur votre Main()
nécessaire pour une prise en charge complète de COM.
J'utilise vsCode (pas visual studio), j'ai donc dû ajouter à mon fichier csproj le xml suivant : <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp3.1</TargetFramework> <UseWPF>true</UseWPF> <UseWindowsForms>true</UseWindowsForms> </PropertyGroup> </Project>
remarquer le Microsoft.NET.Sdk.WindowsDesktop et le UseWPF>true</UseWPF> et le UseWindowsForms>true</UseWindowsForms>.
J'ai récemment voulu faire cela et j'ai constaté que je n'étais satisfait d'aucune des réponses données ici.
Si vous suivez les conseils de Marc et définissez le type de sortie sur Console Application, il y a deux problèmes :
1) Si vous lancez l'application à partir de l'Explorer, vous obtenez une fenêtre de console gênante derrière votre formulaire qui ne disparaît pas jusqu'à ce que votre programme se termine. Nous pouvons atténuer ce problème en appelant FreeConsole avant de montrer l'interface graphique (Application.Run). Le problème ici est que la fenêtre de la console apparaît toujours. Elle disparaît immédiatement, mais reste tout de même présente pendant un moment.
2) Si vous le lancez depuis une console et que vous affichez une interface graphique, la console est bloquée jusqu'à ce que l'interface graphique sorte. Ceci est dû au fait que la console (cmd.exe) pense qu'elle doit lancer les applications Console de manière synchrone et les applications Windows de manière asynchrone (l'équivalent unix de "myprocess &").
Si vous laissez le type de sortie comme Application Windows, mais correctement appelle AttachConsole, vous n'obtenez pas une deuxième fenêtre de console lorsqu'elle est invoquée à partir d'une console et vous n'obtenez pas la console inutile lorsqu'elle est invoquée à partir de l'explorateur. La façon correcte d'appeler AttachConsole est de lui passer -1. Ainsi, notre processus s'attache à la console de notre processus parent (la fenêtre de console qui nous a lancé).
Cependant, cela pose deux problèmes différents :
1) Comme la console lance les applications Windows en arrière-plan, elle affiche immédiatement l'invite et permet de poursuivre la saisie. D'un côté, c'est une bonne nouvelle, la console n'est pas bloquée sur votre application GUI, mais dans le cas où vous voulez envoyer la sortie vers la console et ne jamais montrer l'interface graphique, la sortie de votre programme vient après l'invite et aucune nouvelle invite n'est affichée lorsque vous avez terminé. Cela semble un peu confus, sans compter que votre "application console" s'exécute en arrière-plan et que l'utilisateur est libre d'exécuter d'autres commandes pendant son exécution.
2) La redirection du flux est également perturbée, par exemple, "myapp some parameters > somefile" ne redirige pas. Le problème de la redirection de flux nécessite une quantité significative de p/Invoke pour réparer les handles standards, mais il est soluble.
Après de nombreuses heures de recherche et d'expérimentation, j'en suis arrivé à la conclusion qu'il n'existe aucun moyen de faire cela parfaitement. Vous ne pouvez tout simplement pas obtenir tous les avantages de la console et de la fenêtre sans aucun effet secondaire. Il s'agit de choisir les effets secondaires les moins gênants pour votre application.
Voici la meilleure méthode que j'ai trouvée : Tout d'abord, définissez le type de sortie de vos projets sur "Application Windows", puis P/Invoke AllocConsole pour créer une fenêtre console.
internal static class NativeMethods
{
[DllImport("kernel32.dll")]
internal static extern Boolean AllocConsole();
}
static class Program
{
static void Main(string[] args) {
if (args.Length == 0) {
// run as windows app
Application.EnableVisualStyles();
Application.Run(new Form1());
} else {
// run as console app
NativeMethods.AllocConsole();
Console.WriteLine("Hello World");
Console.ReadLine();
}
}
}
C'est très simple à faire :
Il suffit d'ajouter l'attribut et le code suivants à votre méthode principale :
[STAThread]
void Main(string[] args])
{
Application.EnableVisualStyles();
//Do some stuff...
while(!Exit)
{
Application.DoEvents(); //Now if you call "form.Show()" your form won´t be frozen
//Do your stuff
}
}
Maintenant vous êtes pleinement capable de montrer WinForms :)
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.