2012-01-20 4 views
4

У меня есть приложение, которое имеет следующие Main:Почему выход приложения не отображается?

static void Main(string[] args) 
{ 
    Console.WriteLine("started"); 
    if (args.Length == 0) 
    { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      Application.Run(new Form1()); 
    } 
    else 
    { 
      File.WriteAllText("./file.txt", "hello"); 
    } 
} 

Я хочу, чтобы это поддерживает запуск из командной строки, которые будут использоваться в некоторых сценариях, а также работает как приложение с графическим интерфейсом. Однако, если я запустил его из командной строки и передал ему параметр, я вижу, что файл создается, но я не вижу ни одного из результатов, созданных Console.WriteLine. Почему это?

+2

Если ваш тип приложения не «Консоль» Я думаю, что вы не можете увидеть выходные сообщения, отправленные с 'Console.WriteLine' – Marco

+1

Если вы отладки из Visual Studio, я думаю, что вы делаете. –

+0

@RichardEv: да, в окне «Выход» – Marco

ответ

0

Как указал Марко, вы пробовали установить тип вывода вашего приложения в «Консольное приложение»?

+0

OP хочет, чтобы приложение работало как консоль при запуске с параметрами и как GUI, когда нет. – Marco

2

Он не будет работать Becase:

Это потому, что окно консоли, которая запустила свои WinForms приложения относится к процессу cmd.exe, который отделен от вашего процесса приложения WinForms.

Я нашел это в this article который также предлагает некоторые обходной путь с AttachConsole Win32 method

3

Я думаю, что я нашел проблему, пожалуйста, прости меня, если я ошибаюсь.
Когда вы создаете приложение GUI и запускаете его из окна консоли, его стандартный выходной поток не отправляется в ранее открытое окно консоли, поэтому он не отображается.
Но если вы попытаетесь запустить yourexe.exe > test.txt вы можете увидеть все, что вы написали с Console.WriteLine

+1

Интересно, что 'yourexe.exe> ​​test.txt' получает выход – Geo

+0

@Tempus: ну,'> 'сообщает консоли перенаправить стандартный вывод в файл ... и класс' Console' записывает на стандартный вывод;) – Marco

+0

Да , Я это понимаю :). Я не знал о командной строке посредника, которая запускает графическое приложение. Мне интересно, что его вывод отправляется в следующую командную строку. – Geo

1

Посмотреть этот пост Raymond Chen: How do I write a program that can be run either as a console or a GUI application?

Выдержки:

Вы не можете, но вы можете попробовать подделать его.

[...]

Есть некоторые люди, которые хотят, чтобы написать то, что я называю «оппортунистической» консольную программу. Это программы, которые будут использовать консоль своего родителя, если они доступны, но не хотят, чтобы консоль была создана для них, если нет. Ядро не поддерживает этот тип программы, но это не остановило некоторых людей от появления clever workarounds.

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

Windows вынуждает вас принять решение во время компиляции: это приложение будет использовать консоль (в этом случае он всегда имеет консольное окно и открывает новый, если он был запущен из значка или в меню «Пуск»), или он не будет использовать консоль (в этом случае он не может прямого ввода или вывода в консольное окно, из которого он был запущен - он может, однако, create a new console window). Если вы хотите всегда иметь консоль, измените тип сборки на «Консольное приложение»; если вы не хотите иметь консоль, оставьте ее как «Приложение Windows».

Умные обходные цитируемые в пост Раймонда, в случае ссылки гнили, являются Devenv (Visual Studio) и ILDASM:

В случае VisualStudio, есть на самом деле два бинарных файла: devenv.com и devenv.exe , Devenv.com - это консольное приложение. Devenv.exe - графическое приложение. Когда вы вводите devenv, из-за правила проверки Win32, выполняется devenv.com. Если вход отсутствует, devenv.com запускает файл devenv.exe и выходит из него. Если есть входы, devenv.com обрабатывает их как обычное консольное приложение.

В случае ildasm имеется только один двоичный файл: ildasm.exe. Он сначала компилируется как приложение с графическим интерфейсом. Позже editbin.exe используется, чтобы пометить его как консольную подсистему. В своем основном методе он определяет, нужно ли его запускать в режиме консоли или графического интерфейса. Если это нужно для запуска в режиме графического интерфейса, оно возобновляет себя как графическое приложение.

2

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

В основном это приложение имеет три режима

  • bParentConsoleMode, который будет использовать родительскую консоль, если запустить из командной строки
  • bUsingOwnConsole если дважды щелкнуть в проводнике, вам придется создать новую консоль
  • Наконец когда ни одно из указанных выше не верно, оно выполняется как приложение обычной формы.

    static class Program 
    { 
        [DllImport("kernel32.dll")] 
        static extern bool AttachConsole(int dwProcessId); 
        private const int ATTACH_PARENT_PROCESS = -1; 
    
    
        [DllImport("kernel32.dll")] 
        private static extern bool AllocConsole(); 
    
        [STAThread] 
        static void Main() 
        { 
         bool bParentConsoleMode = true; 
         bool bUsingOwnConsole = true; 
         if (bParentConsoleMode) 
         { 
          AttachConsole(ATTACH_PARENT_PROCESS); 
          Console.WriteLine("Using parent console"); 
          Console.ReadLine(); 
    
         } 
         else if (bUsingOwnConsole) 
         { 
          AllocConsole(); 
          Console.WriteLine("Using own console"); 
          Console.ReadLine(); 
         } 
         else //gui mode 
         { 
          Console.WriteLine("This is cool"); 
    
          Application.EnableVisualStyles(); 
          Application.SetCompatibleTextRenderingDefault(false); 
          Application.Run(new Form1()); 
         } 
        } 
    } 
    
+0

Это интересно, но это открывает другую командную строку. Невозможно, чтобы вывод отображался в той же командной строке? – Geo

+0

@Tempus, пожалуйста, посмотрите на мое редактирование. –

0

Я использовал следующий код, чтобы сделать что-то подобное:

Console.WriteLine("started"); 
if (args.Length == 0) 
{ 
    ProcessForConsole(argsParser); 
} 
else 
{ 
    NativeMethods.FreeConsole(); 
    Application.EnableVisualStyles(); 
    Application.SetCompatibleTextRenderingDefault(false); 
    Application.Run(new Form1());     
}  

. . . .

[DllImport("kernel32.dll", SetLastError = true)] 
    public static extern int FreeConsole(); 

Установите основное приложение как консольное приложение, а затем FreeConsole, чтобы отсоединить его.

Процесс может использовать функцию FreeConsole для отсоединения от ее консоли. Если другие процессы используют консоль, консоль не будет уничтожена, но процесс, который называется FreeConsole, не может ссылаться на него. Консоль закрывается, когда последний подключенный к ней процесс завершает работу или вызывает FreeConsole.

От microsoft.

+0

Это более того или другого, а не того и другого. В первом вы используете консоль и не используете формы, во втором вы отпускаете консоль и используете формы. – AidanO

Смежные вопросы