2012-03-28 3 views
8

Я хотел был бы отделить мою программу от пульта очень как wget -b. Фрагмент кода может выглядетьC# close standard out

static void Main(string[] args) 
{ 
    var settings = new Settings(args); 
    if (settings.Background) 
    { 
     /*Tell the user what's going on.*/ 
     System.Console.WriteLine("Detatching from console. The program will still be running."); 
     System.Console.Out.Close(); 
    } 
    /*do work then exit.*/ 
} 

Но System.Console.Out.Close(); не делает правильно.

Чтобы уточнить, «правильная вещь» при запуске этой программы с консоли должна появиться снова. Или, при запуске этой программы от explorer.exe, консольное окно должно закрываться.

Пожалуйста, дайте мне знать, если я не буду чист.

+0

, чтобы быть уверенным, что я понял ваш вопрос: если вы наберете yourprogram.exe в CMD-окне, должно появиться новое. если вы дважды щелкните приложение в проводнике, то вы хотите закрыть консоль? что вы хотите сделать с вашим приложением? –

+0

Консольное приложение без консоли? Не могу дождаться ответа на этот вопрос ... –

+1

Если вы хотите, чтобы приложение, работающее в фоновом режиме, оставалось в фоновом режиме, вам нужен сервис Windows. Если вы просто хотите периодически запускать приложение, вы можете подумать о его запуске с планировщиком задач. – jlafay

ответ

1

Источник wget, на который вы ссылаетесь, является here. Вы заметите, что в строках mswindows.c 193 - 314 реализована процедура fork. Они порождают новый экземпляр wget и передают ему те же параметры.

Комментарии информативны тоже:

Windows, не поддерживает вилку() вызов; поэтому мы подделываем его, вызывая другую копию Wget с теми же аргументами, с которыми мы были вызваны.

А на линии 102:

Под Windows 9x, если бы мы начали с 16-разрядного процесса ... родительский процесс должен возобновиться сразу. В NT ... это бесполезный жест, поскольку родитель будет ждать, пока мы закончим, прежде чем возобновиться.

Короткий ответ кажется «Не делай этого».

+0

Да - вы могли подделать его или подойти очень близко, но он очень строго «не поощряется». –

+0

Можете ли вы подумать о другой реализации? –

+0

Если вы не возражаете, я спрашиваю: какая цель печатать что-то или что-то возвращать на консоль, прежде чем делать ... что бы это ни делала остальная консоль? Разделение двух половинок имеет смысл? Будет ли запущенный сервис, который компонент командной строки может отправить команду, а затем прекратить, имеет смысл? –

1

Доступно 3 канала для любого приложения консоли: STDIN, STDOUT, STDERR. Традиционно все 3 должны быть закрыты для приложения, чтобы выпустить консоль.

В Windows, однако, существует метод API для этого: FreeConsole ... и pinvoke.net.

Редактировать: Другое сообщение о том, что это невозможно без запуска фонового процесса: How to make a windowless/command-line application return but continue executing in background? ... В Unix этого будет достаточно с fork();.

+0

Это не работает. 'static void Main (string [] args) {System.Console.Out.Close(); System.Console.In.Close(); System.Console.Error.Close(); System.Console.WriteLine ("detatched.");} 'Показывает, что консоль не отсоединена. –

+0

Я пробовал 'FreeConsole'. Кажется, почти * работает. Я больше не могу использовать консоль для записи в стандартную версию после ее освобождения, но интерпретатор команд до сих пор не возвращает консоль. –

+0

@ LimitedAtonement вы запустили приложение, запустив cmd.exe, а затем запустив приложение? Чтобы вернуться в оболочку, вам понадобится копия cmd.exe, подключенная к той же консоли. –

0

Чтобы уточнить, «правильная вещь» при запуске этой программы с консоли должна появиться снова. Или, при запуске этой программы из explorer.exe, окно консоли должно закрываться.

Это не значит, что вы хотите «закрыть окно консоли», вы хотите, чтобы он не существовал. Есть очень простой способ получить то, что вы хотите: не создавайте консольное приложение. :-)

Если вы строите из командной строки, используйте CSC /target:winexe .... Это создаст программу Windows, которая никогда не будет связана с какой-либо командной строкой.

+0

Это не совсем мое намерение. Я хочу консоль на некоторое время, а затем я хочу от нее отделиться. Некоторое время назад я отредактировал вопрос, чтобы прояснить это требование. Пример кода теперь может быть более понятным. –

1

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

Таким образом, у вас есть приложение, которое может работать в фоновом режиме, но при необходимости может отображать и скрывать окно консоли. Хотя, насколько я помню, существуют некоторые различия между этими консольными окнами и обычными командами командной строки Windows, поэтому он может не работать для того, что вы хотите.

+0

Спасибо за ответ. Это, конечно, идея открыть новое окно консоли, но я надеялся только взаимодействовать с существующим консольным окном. Я не думаю, что у меня проблемы с 'FreeConsole'; он действует так, как надо. Я знаю «AllocConsole» и т. Д. Проблема в том, что интерпретатор команд (cmd или powershell) ждет завершения * процесса *, прежде чем вернуться к командному интерпретатору. Еще раз спасибо. –