Связанный:
Должен ли я включить режим командной строки в моих приложениях?
Как получить стандартный вывод родительского процесса?
Может ли консольное приложение определить, запущено ли оно из Проводника?
Я хочу создать консольное приложение, которое обычно запускается из командной строки.
Но, если дважды щелкнуть его из Проводника (в отличие от запуска из командной строки cmd.exe), я бы хотел, чтобы программа НЕ отображала окно консоли.
Я хочу избежать этого:
Возможно ли это?
РЕДАКТИРОВАТЬ Я полагаю, еще один способ задать вопрос: Возможно ли, чтобы программа знала, как она была вызвана - двойным щелчком или командной строкой ?
Я работаю в .NET, в Windows.
РЕДАКТИРОВАТЬ 2: С это Старое новое сообщение в блоге Я узнал кое-что хорошее. Вот что я знаю сейчас ...
В Windows EXE-файлы помечаются как GUI или не-GUI. Для csc.exe это выбирается с помощью /target:winexe
или /target:exe
. Перед выполнением первой инструкции в процессе ядро Windows устанавливает среду выполнения. В этот момент, если EXE помечен как GUI, ядро устанавливает для stdin / stdout для процесса значение NULL, а если не для GUI (командной строки), ядро создает консоль и устанавливает для этого stdin / stdout для этого процесса. приставка.
При запуске процесса, если нет стандартного ввода / вывода (== /target:winexe
), вызов немедленно возвращается. Итак, запустив приложение с графическим интерфейсом из cmd.exe, вы сразу получите ответ cmd. Если есть stdin / stdout и запускается из cmd.exe, то родительский cmd.exe ожидает завершения процесса.
«Немедленный возврат» важен, потому что если вы закодируете приложение с графическим интерфейсом для присоединения к консоли его родителя, вы сможете выполнить console.writeline и т. Д. Но приглашение cmd.exe активно. Пользователь может вводить новые команды, запускать новый процесс и так далее. Другими словами, от winexe простое подключение к родительской консоли с помощью AttachConsole(-1)
не превратит его в консольное приложение.
На данный момент я думаю, что единственный способ разрешить приложению использовать консоль, если она вызывается из cmd.exe, и НЕ использовать ее при двойном щелчке, это определить exe как обычный exe консоли ( /target:exe
) и скрыть окно при запуске, если это необходимо. Вы все еще получаете окно консоли, появляющееся кратко.
Я до сих пор не понял, как узнать, запущен ли он из explorer или cmd.exe, но я все ближе ...
ОТВЕТЫ
Невозможно создать консольное приложение, которое не отображает консольное окно.
можно создать консольное приложение, которое очень быстро скрывает свое окно, но не так быстро, как если бы окно никогда не появлялось.
Теперь, чтобы определить, было ли запущено консольное приложение из проводника, некоторые предложили взглянуть на консоль, в которой оно запущено
(из ответа mgb и KB, статья 99115 ):
int left = Console.CursorLeft;
int top = Console.CursorTop;
bool ProcessWasRunFromExplorer = (left==0 && top==0);
Здесь указывается, был ли процесс запущен в его собственной консоли, но не был ли он проводником. Двойной щелчок в проводнике сделает это, но и Start.Process () из приложения сделает то же самое.
Если вы хотите по-другому относиться к этим ситуациям, используйте это, чтобы узнать имя родительского процесса:
System.Console.WriteLine("Process id: {0}", Process.GetCurrentProcess().Id);
string name = Process.GetCurrentProcess().ProcessName ;
System.Console.WriteLine("Process name: {0}", name);
PerformanceCounter pc = new PerformanceCounter("Process", "Creating Process Id", name);
Process p = Process.GetProcessById((int)pc.RawValue);
System.Console.WriteLine("Parent Process id: {0}", p.Id);
System.Console.WriteLine("Parent Process name: {0}", p.ProcessName);
// p.ProcessName == "cmd" or "Explorer" etc
Чтобы быстро скрыть окно после запуска процесса, используйте:
private static readonly int SW_HIDE= 0;
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern Boolean ShowWindow(IntPtr hWnd, Int32 nCmdShow);
....
{
IntPtr myHandle = Process.GetCurrentProcess().MainWindowHandle;
ShowWindow(myHandle, SW_HIDE);
}
Если вы создаете winexe
(приложение WinForms) и при необходимости подключаетесь к родительской консоли при помощи AttachConsole(-1)
, вы не получите эквивалент обычного консольного приложения. Для winexe родительский процесс (например, cmd.exe) вернется в командную строку сразу после запуска приложения с графическим интерфейсом. Другими словами, командная строка активна и готова к вводу, в то время как только что запущенный процесс может выдавать вывод. Это сбивает с толку и, вероятно, полезно только для отладки приложений winforms.
Это сработало для меня.