Приложение .NET работает как Windows Form или как консольное приложение
Я хочу, чтобы одно из моих приложений Windows Forms запускалось программно - из командной строки. В процессе подготовки я отделил логику в своем классе от Формы. Теперь я застрял, пытаясь заставить приложение переключиться туда и обратно на основе наличия аргументов командной строки.
Вот код для основного класса:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
string[] args = Environment.GetCommandLineArgs();
if (args.Length > 1) // gets passed its path, by default
{
CommandLineWork(args);
return;
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
private static void CommandLineWork(string[] args)
{
Console.WriteLine("It works!");
Console.ReadLine();
}
где Form1
- моя форма, а строка It works!
является просто заполнителем для фактической логики.
Прямо сейчас, когда вы запускаете это из Visual Studio (с аргументами командной строки), фраза It works!
печатается в Output. Однако при запуске файла /bin/Debug/Program.exe(или/Release, если на то пошло) приложение сбой.
Я собираюсь сделать это правильно? Будет ли иметь смысл (т.е. Меньше времени на разработку), чтобы мой логический класс был DLL, который загружается двумя отдельными приложениями? Или есть что-то совершенно иное, что я не знаю?
Спасибо заранее!
Ответы
Ответ 1
Вам понадобится P/Invoke AllocConsole(), если вы обнаружите аргумент командной строки. Проверьте мой ответ в этот поток для требуемого кода. Образец С# находится далее на странице. Повторяется здесь, потому что я не доверяю этому сайту crummy:
using System;
using System.Windows.Forms;
namespace WindowsApplication1 {
static class Program {
[STAThread]
static void Main(string[] args) {
if (args.Length > 0) {
// Command line given, display console
AllocConsole();
ConsoleMain(args);
}
else {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
private static void ConsoleMain(string[] args) {
Console.WriteLine("Command line = {0}", Environment.CommandLine);
for (int ix = 0; ix < args.Length; ++ix)
Console.WriteLine("Argument{0} = {1}", ix + 1, args[ix]);
Console.ReadLine();
}
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
private static extern bool AllocConsole();
}
}
Ответ 2
Да, было бы лучше сделать два frontend -exex (один для командной строки и один для оконного).
Основная причина заключается в том, что вы должны указать тип вывода для своего проекта (либо в командной строке, либо в приложении Windows, и вы не можете выбрать оба.
Таким образом, вы должны всегда использовать тип вывода приложения Windows (который приходит с накладными расходами для системы обмена сообщениями Windows и не дает вам "реальной" командной строки).
Ответ 3
Не уверен, что это имеет значение, но вместо
static void Main()
{
string[] args = Environment.GetCommandLineArgs();
вы можете вместо этого поставить
static void Main(string[] args)
{
Ответ 4
Вы собираетесь запустить его в качестве реального консольного приложения, попросив пользователя ввести данные и т.д. или вы просто начнете его с некоторых аргументов, чтобы его можно было запустить из пакетного файла или запланированной задачи или подобное?
Если это настоящее консольное приложение, я согласен с Foxfire, что, вероятно, стоит иметь 2 exe файла, но в остальном я бы сохранил его как один exe. Я сделал много из них без каких-либо проблем.
Какое точное исключение происходит?
Ответ 5
Перейдите к свойствам проекта
На вкладке Application вы увидите раскрывающийся список с именем Output Type. Измените это на Console Application.
Там у вас есть как окно, так и консоль. Теперь ваш код с аргументом команды должен работать.