Подтвердить что ты не робот

Может ли консольное приложение Win32 определить, запущен ли он из проводника или нет?

Мне нужно создать консольное приложение, которое нуждается в определенных параметрах. Если они отсутствуют или ошибочны, я печатаю сообщение об ошибке.

Теперь проблема: если кто-то запускает программу из проводника, дважды щелкнув окно консоли, сразу исчезает. (Но приложение не совсем бесполезно из проводника, вы можете перетащить на него файлы, и это сработает)

Я всегда мог ждать нажатия клавиши, но я не хочу, чтобы пользователь запустил его из командной строки.

Есть ли способ различать эти ситуации?

4b9b3361

Ответ 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] от работы.