как запустить winform из консольного приложения? - PullRequest
62 голосов
/ 10 ноября 2008

Как создать, выполнить и контролировать winform из консольного приложения?

Ответы [ 10 ]

88 голосов
/ 10 ноября 2008

Самый простой вариант - запустить проект форм Windows, а затем изменить тип вывода на Консольное приложение. Либо просто добавьте ссылку на System.Windows.Forms.dll и начните кодировать:

using System.Windows.Forms;

[STAThread]
static void Main() {
    Application.EnableVisualStyles();
    Application.Run(new Form()); // or whatever
}

Важным битом является [STAThread] в вашем Main() методе, необходимом для полной поддержки COM.

32 голосов
/ 16 июня 2012

Я недавно хотел сделать это и обнаружил, что не был рад ни одному из ответов здесь.

Если вы последуете совету Марка и установите для типа вывода значение Консольное приложение, возникнут две проблемы:

1) Если вы запустите приложение из Explorer, вы получите раздражающее окно консоли за вашей формой, которое не исчезнет, ​​пока ваша программа не закроется. Мы можем решить эту проблему, вызвав FreeConsole перед отображением графического интерфейса (Application.Run). Раздражает то, что окно консоли все еще появляется. Он немедленно уходит, но, тем не менее, на мгновение.

2) Если вы запускаете его из консоли и отображаете графический интерфейс, консоль блокируется до выхода из графического интерфейса. Это связано с тем, что консоль (cmd.exe) считает, что должна запускать консольные приложения синхронно, а приложения Windows асинхронно (unix-эквивалент «myprocess &»).


Если вы оставите тип вывода как Приложение Windows, но правильно вызовите AttachConsole, вы не получите второе окно консоли при вызове из консоли и не получите ненужную консоль при вызове из Проводника. Правильный способ вызова AttachConsole - передать ему -1. Это заставляет наш процесс подключаться к консоли нашего родительского процесса (окно консоли, которое запустило нас).

Однако у этого есть две разные проблемы:

1) Поскольку консоль запускает приложения Windows в фоновом режиме, она сразу отображает подсказку и разрешает дальнейший ввод. С одной стороны, это хорошая новость: консоль не блокируется в вашем приложении с графическим интерфейсом, но в случае, когда вы хотите вывести вывод на консоль и никогда не показывать графический интерфейс, вывод вашей программы идет после приглашения, и новое приглашение не отображается. отображается, когда вы закончите. Это выглядит немного странно, не говоря уже о том, что ваше «консольное приложение» работает в фоновом режиме, и пользователь может выполнять другие команды во время работы.

2) Перенаправление потока также испорчено, например, «myapp некоторые параметры> somefile» не удается перенаправить. Проблема перенаправления потока требует значительного количества p / Invoke для исправления стандартных дескрипторов, но это решаемо.


После многих часов охоты и экспериментов я пришел к выводу, что не существует способа сделать это идеально. Вы просто не можете получить все преимущества консоли и окна без каких-либо побочных эффектов. Это вопрос выбора того, какие побочные эффекты наименее раздражают для целей вашего приложения.

23 голосов
/ 11 ноября 2008

Вот лучший метод, который я нашел: Сначала установите тип вывода проекта «Приложение Windows», затем P / Invoke AllocConsole, чтобы создать окно консоли.

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();
        }
    }

}
6 голосов
/ 02 декабря 2011

Это очень просто сделать:

Просто добавьте следующий атрибут и код в свой метод Main:

[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
   }
}

Теперь вы полностью можете показать WinForms:)

4 голосов
/ 10 ноября 2008

Вы можете создать проект winform в VS2005 / VS2008, а затем изменить его свойства в качестве приложения командной строки. Затем он может быть запущен из командной строки, но все равно откроет winform.

0 голосов
/ 13 июня 2018

Все приведенные выше ответы очень помогают, но я подумал добавить еще несколько советов для начинающего.

Итак, вы хотите что-то сделать с Windows Forms, в консольном приложении:

Добавьте ссылку на System.Windows.Forms.dll в проекте консольного приложения в обозревателе решений. (Щелкните правой кнопкой мыши на Solution-name-> add-> Reference ...)

Укажите пространство имен в коде: using System.Windows.Forms;

Объявите необходимые свойства в вашем классе для элементов управления, которые вы хотите добавить в форму.

например. int Left { get; set; } // need to specify the LEFT position of the button on the Form

А затем добавьте следующий фрагмент кода в Main():

static void Main(string[] args)
{
Application.EnableVisualStyles();
        Form frm = new Form();  // create aForm object

        Button btn = new Button()
        {
            Left = 120,
            Width = 130,
            Height = 30,
            Top = 150,
            Text = "Biju Joseph, Redmond, WA"
        };
       //… more code 
       frm.Controls.Add(btn);  // add button to the Form
       //  …. add more code here as needed

       frm.ShowDialog(); // a modal dialog 
}
0 голосов
/ 20 апреля 2018

Если вы хотите выйти из Form Freeze и использовать редактирование (например, текст для кнопки), используйте этот код

Form form = new Form();
Form.Button.Text = "randomText";
System.Windows.Forms.Application.EnableVisualStyles();
System.Windows.Forms.Application.Run(form);
0 голосов
/ 22 августа 2015

Все зависит от вашего выбора, от того, как вы реализуете.
а. Прикрепленный процесс, например: ввод в форму и печать на консоли
б. Независимый процесс, например: запустить таймер, не закрывать даже при выходе из консоли.

для,

Application.Run(new Form1());
//or -------------
Form1 f = new Form1();
f.ShowDialog();

для б, Используйте поток или задание что-нибудь, Как самостоятельно открыть форму выигрыша?

0 голосов
/ 09 июля 2015

Это сработало для моих нужд ...

Task mytask = Task.Run(() =>
{
    MyForm form = new MyForm();
    form.ShowDialog();
});

Это запускает from в новой теме и не освобождает ее, пока форма не будет закрыта. Task в .Net 4 и более поздних версиях.

0 голосов
/ 10 ноября 2008

Вы должны иметь возможность использовать класс Application так же, как приложения Winform. Вероятно, самый простой способ начать новый проект - это сделать то, что предложил Марк: создать новый проект Winform, а затем изменить его в настройках консольного приложения

...