Windows Forms + управляют от консоли в C#

Я считал несколько тем о программах, которые комбинируют Windows Forms и консольные приложения, но кажется, что мой вопрос еще не был решен. Действительно ли возможно запустить программу от cmd-строки и смочь управлять приложением через формы и через команды cmd-строки? Это означает:

  • для обычных пользователей приложения для управления приложением через (Windows Forms) формы,
  • для отладки и опытных пользователей, чтобы управлять приложением через консоль (и дополнительно видеть, что происходит в Windows Forms)),

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

8
задан Peter Mortensen 21 April 2012 в 15:30
поделиться

6 ответов

Это несложно, просто вызовите функцию API AllocConsole () P /, чтобы создать свою собственную консоль. Например, сделайте так, чтобы ваш файл исходного кода Program.cs выглядел так:

  static class Program {
    [STAThread]
    static void Main() {
      Application.EnableVisualStyles();
      Application.SetCompatibleTextRenderingDefault(false);
#if DEBUG
      CreateConsole();
#endif
      Application.Run(new Form1());
    }

    static void CreateConsole() {
      var t = new System.Threading.Thread(() => {
        AllocConsole();
        for (; ; ) {
          var cmd = Console.ReadLine();
          if (cmd.ToLower() == "quit") break;
          // Etc...
        }
        FreeConsole();
      });
      t.IsBackground = true;
      t.Start();
    }
    [System.Runtime.InteropServices.DllImport("kernel32.dll")]
    private static extern bool AllocConsole();
    [System.Runtime.InteropServices.DllImport("kernel32.dll")]
    private static extern bool FreeConsole();
  }
5
ответ дан 5 December 2019 в 21:18
поделиться

Вам просто нужно запустить приложение Windows Forms с ApplicationContext вместо самой формы. В этом случае вы не зависите от отображаемой основной формы и можете действовать как консольное приложение.

Вы также можете просто создать исполняемый файл командной строки и самостоятельно связать его с библиотеками Windows Forms, чтобы использовать их.

Другой способ - использовать какой-то стартер, запускающий приложение Windows Forms, и инструмент командной строки, который взаимодействует с приложением Windows Forms через локальную сеть или какое-то другое взаимодействие между процессами, D -Автобус или похожие системы - многие пути ведут в Рим ...

1
ответ дан 5 December 2019 в 21:18
поделиться

Да, то, что вы хотите, очень возможно. У вас есть варианты. Некоторые из них я могу назвать...:

  1. Используйте UI Automation для написания приложения-контроллера, которое может подключаться к приложению Windows Forms и управлять им. Это новое в Windows Vista. Существуют управляемые классы, упакованные в пространство имен System.Windows.Automation, которые впервые появились в WPF, появившемся в .NET 3.0. (Теперь, когда я думаю об этом, я не уверен, что "новое в Windows Vista" - это правда. Возможно, это "новое в .NET 3.0", что подразумевает, что он также работает на Windows XP. Hmmm....) Автоматизация пользовательского интерфейса не требует изменения кода приложения Windows Forms, но она может быть низкоуровневой, поскольку вам нужно программировать каждый щелчок мыши или вырезание/вставку. Смотрите ответ на вопрос Stack Overflow Есть ли способ управлять сторонним EXE-файлом из VB.NET?.

  2. Модифицируйте ваше приложение Windows Forms так, чтобы оно раскрывало свою функцию через интерфейс WM_COPYDATA. Затем ваше клиентское приложение сможет взаимодействовать с ним. Опять же, модель здесь представляет собой два разных приложения, одно из которых может контролировать или опрашивать другое. Инструмент .NET Reflector является хорошим примером такого подхода. Существует контроллер ReflectorController, доступный как часть проекта ReflectorAddins на CodePlex. Контроллер представляет собой инструмент командной строки, который может посылать WM_COPYDATA сообщения в Reflector, чтобы сказать ему открыть новую сборку, перейти к определенному классу и так далее.

    Код для контроллера: http://reflectoraddins.codeplex.com/sourcecontrol/network/Show?projectName=reflectoraddins&changeSetId=29526#19979

    Этот подход подойдет для любого приложения Windows Forms. Вам нужно будет переопределить метод WndProc. Чтобы узнать, как это сделать, посмотрите статью The Code Project Use WM_COPYDATA to send data to/from C++ and C# Windows processes.

    Я также использовал этот подход для создания монитора выполнения на базе Windows Forms, который может визуально отображать ход выполнения давно запущенных тестов.

  3. В своем приложении выставляйте объект COM-сервера, который можно программировать. Именно так Microsoft раскрывает функции Office для приложений. Office Automation позволяет любой программе с поддержкой COM (C#, VBScript, PowerShell, Perl, PHP и т.д.) "управлять" приложениями Office. При этом приложение Office остается видимым. Этот подход также потребует дополнительного кода в приложении Windows Forms; в частности, вам придется разместить COM-объект и подключить его к слою пользовательского интерфейса. Это может быть предпочтительнее, если вы хотите максимальной гибкости для суперпользователей - они могут писать свои собственные сценарии для управления этим компонентом.

Я уверен, что есть и другие варианты.

1
ответ дан 5 December 2019 в 21:18
поделиться

Я помню, как IronPython использовался в демонстрации, управляющей Windows Forms из интерфейса командной строки Python ( IDLE ).

Редактировать: Мне не удалось найти исходное видео, но это должно показать, что возможно без особых усилий. Смотрите это видео и переходите к 19:00.

0
ответ дан 5 December 2019 в 21:18
поделиться

Обычно, когда вы смотрите на свое приложение, у вас есть уровень пользовательского интерфейса и бизнес-уровень (и уровень данных, и кто знает намного больше уровней). Вы можете думать о консольном клиенте как о слое пользовательского интерфейса (с вводом простых команд), а о клиенте Windows Forms как о другом.

Просто проверьте при запуске приложения аргументы командной строки. Если указаны аргументы, создайте экземпляры простых консольных классов, в противном случае создайте экземпляры (возможно, более сложных) классов Windows Forms.

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

0
ответ дан 5 December 2019 в 21:18
поделиться

Это возможно. Вам нужно будет изучить многопоточность формы Windows Forms, возможно, с использованием отдельного домена приложения в рамках того же процесса. Вы можете изучить создание прокси-объекта (своего рода класса сообщений, наследующего MarshalByRefObject).

0
ответ дан 5 December 2019 в 21:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: