Может ли консольное приложение Win32 определить, запущен ли он из проводника или нет?
Мне нужно создать консольное приложение, которое нуждается в определенных параметрах. Если они отсутствуют или ошибочны, я печатаю сообщение об ошибке.
Теперь проблема: если кто-то запускает программу из проводника, дважды щелкнув окно консоли, сразу исчезает. (Но приложение не совсем бесполезно из проводника, вы можете перетащить на него файлы, и это сработает)
Я всегда мог ждать нажатия клавиши, но я не хочу, чтобы пользователь запустил его из командной строки.
Есть ли способ различать эти ситуации?
Ответы
Ответ 1
См. http://support.microsoft.com/kb/99115, "INFO: Предотвращение исчезновения окна консоли".
Идея состоит в том, чтобы использовать GetConsoleScreenBufferInfo, чтобы определить, что курсор не перемещается из начальной позиции 0,0.
Пример кода из @tomlogic, основанный на указанной статье базы знаний:
// call in main() before printing to stdout
// returns TRUE if program is in its own console (cursor at 0,0) or
// FALSE if it was launched from an existing console.
// See http://support.microsoft.com/kb/99115
#include <stdio.h>
#include <windows.h>
int separate_console( void)
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
if (!GetConsoleScreenBufferInfo( GetStdHandle( STD_OUTPUT_HANDLE), &csbi))
{
printf( "GetConsoleScreenBufferInfo failed: %lu\n", GetLastError());
return FALSE;
}
// if cursor position is (0,0) then we were launched in a separate console
return ((!csbi.dwCursorPosition.X) && (!csbi.dwCursorPosition.Y));
}
Ответ 2
GetConsoleTitle()
Я видел код, который выполняет
if (!GetConsoleTitle(NULL, 0) && GetLastError() == ERROR_SUCCESS) {
// Console
} else {
// GUI
}
НО... Я нашел, что AttachConsole()
более полезно
В С++ (с верхней части головы, и я не программист на С++)
if (!AttachConsole(ATTACH_PARENT_PROCESS)) {
// GUI
} else {
// Console, and you have a handle to the console that already exists.
}
Более эффективен. Кроме того, если вы окажетесь в среде графического интерфейса и хотите остаться там столько, сколько сможете, но позже обнаружите, что произошло что-то катастрофическое, которое действительно могло бы использовать дамп для консольного окна (вы не можете быть заняты написанием окна редактирования окно, чтобы ловить его или прикрепить к системному журналу NT и вытащить MessageBox()
), а затем вы можете AllocConsole()
позже в процессе, когда методы GUI потерпели неудачу.
Ответ 3
Я полагаю, что cmd.exe
задает переменные среды CMDCMDLINE и CMDEXTVERSION при запуске. Поэтому, если они установлены, ваша программа, скорее всего, была запущена из оболочки.
Это не является надежным, но это что-то.
Также можно определить ваш родительский PID несколькими запутанными и, возможно, ненадежными способами, или так я собираюсь. Вы можете посмотреть на это.
Ответ 4
Как насчет ожидания нажатия клавиши при отображении сообщения об ошибке, а не в других случаях?
Ответ 5
Это работает как прелесть:
@echo off
for %%x in (%cmdcmdline%) do if /i "%%~x"=="/c" goto nonconsole
:console
<do something>
goto exit
:nonconsole
<do something>
pause
:exit
Скопирован из этой темы. Я также попытался оценить% cmdcmdline% самостоятельно, однако есть проблема с кавычками символов ( "), которая предотвращает что-то вроде, если" % cmdcmdline% "==" % ComSpec% "goto [target] от работы.