Окно консоли консольного приложения - visual c++

Я сделал код C++ в Visual Studio, консольное приложение. Мой вопрос в том, как запустить последний exe без консоли (процесс виден только из диспетчера задач)

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

есть ли в Visual Studio какой-либо вариант или флаг для этого? (что-то вроде флага -mwindows в g ++)

Заранее спасибо

2
0
378
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В Project Properties на странице Configuration Properties-> Linker-> System вам необходимо установить значение SubSystem на Windows (/SUBSYSTEM:WINDOWS). По умолчанию для нового проекта консольного приложения используется Console (/SUBSYSTEM:CONSOLE), что заставляет Windows выделять новую консоль или подключаться к консоли родительского процесса при запуске вашей программы.

enter image description here


Вам также необходимо изменить функцию main на WinMain. Подпись для WinMain:

int CALLBACK WinMain(
  _In_ HINSTANCE hInstance,
  _In_ HINSTANCE hPrevInstance,
  _In_ LPSTR     lpCmdLine,
  _In_ int       nCmdShow)
{
    // Your code here
}

При описанном выше подходе дочерние консольные процессы по-прежнему будут создавать консольные окна. Поскольку в комментарии вы заявили, что хотите использовать popen, вы не можете легко использовать обычный способ вызова CreateProcess с помощью SW_HIDE.

Что вы действительно хотите сделать, так это прикрепить к процессу скрытое окно консоли и позволить дочерним процессам наследовать его. Вероятно, это не лучший код, но вот способ сделать это:

// Allocates a hidden console window for this process. This console can be
// inherited by child console processes, preventing them from creating a
// visible console. Returns false if the attempt fails.
bool AllocHiddenConsole()
{
  TCHAR command[] = _T("cmd.exe");
  STARTUPINFO startupInfo{};
  PROCESS_INFORMATION processInfo{};
  startupInfo.cb = sizeof(startupInfo);
  startupInfo.dwFlags = STARTF_USESHOWWINDOW;
  startupInfo.wShowWindow = SW_HIDE;

  if (!CreateProcess(NULL, command, NULL, NULL, FALSE,
    CREATE_NEW_CONSOLE, NULL, NULL, &startupInfo, &processInfo))
  {
    return false;
  }

  bool attached = false;
  for (int i = 0; i < 1000; i++)
  {
    if (AttachConsole(processInfo.dwProcessId))
    {
      attached = true;
      break;
    }
    Sleep(10);
  }

  TerminateProcess(processInfo.hProcess, 0);
  CloseHandle(processInfo.hProcess);
  CloseHandle(processInfo.hThread);

  return attached;
}

Вы также должны упомянуть, что main () должен стать WinMain ().

Hans Passant 10.08.2018 16:08

У меня WinMain функция не может быть перегружена

Mohammed B. 10.08.2018 16:35

@HansPassant: Спасибо, я забыл об этом, потому что я обычно делаю это на C#, где подпись Main не меняется между различными типами приложений.

Dark Falcon 10.08.2018 17:26

Это заставляет многие окна консоли появляться, мигать и исчезать. Они все еще появляются

Mohammed B. 10.08.2018 17:43

Дайте угадаю: ваша программа запускает другие программы, которые также являются консольными приложениями? Это единственное объяснение, которое приходит на ум. Без дополнительной информации о том, что делает ваша программа, я не могу определить, как это исправить.

Dark Falcon 10.08.2018 18:08

Вы правы, мой код внутренне связан с оболочкой Windows (с использованием функции popen). Я думаю, должен быть способ сделать это, это легко делается на python (код также использует функцию popen python) и даже в G ++ с флагом! как может что-то подобное не найти в Visual Studio .....

Mohammed B. 10.08.2018 18:17

Вы не правы. Простой запуск программы, которая порождает консольные программы с pythonw, или использование этого флага g ++ НЕ решит проблему открытия дочерних консолей. Эти два параметра делают то же самое, что и приведенное выше изменение в Visual Studio (они включают запуск программы, ориентированной на подсистему Windows). Полученная программа по-прежнему заставляет дочерние процессы открывать консоль. Вам понадобится использовать CreateProcess, если вы хотите скрыть дочернее окно.

Dark Falcon 10.08.2018 18:33

Примечание: помимо статьи о том, как перенаправить ввод-вывод, вам понадобится установите wShowWindow на SW_HIDE, чтобы также скрыть окно консоли.

Dark Falcon 10.08.2018 18:35

Моя основная цель - "тихий запуск" программного обеспечения, согласно тому, что вы сказали, как лучше всего это сделать? Мое программное обеспечение в значительной степени работает с оболочкой изнутри. Ничего особенного, кроме "тишины"

Mohammed B. 10.08.2018 18:41

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

Dark Falcon 10.08.2018 19:10

@DarkFalcon Рад вашей правке, но у меня есть вопросы по этому поводу. Я не понимаю, что именно заменит код? я буду использовать это каждый раз, когда я выполняю команду? Также как получить ответ? извините, так как я совершенно новичок в win32api.

Mohammed B. 10.08.2018 19:29

Вы вызываете это один раз, прежде чем делать что-либо еще. Ничего не заменяет. Это в дополнение к тому, что вы делаете.

Dark Falcon 10.08.2018 19:42

Значит, вы имеете в виду, что использование _popen () после вызова AllocHiddenConsole () сработает?

Mohammed B. 10.08.2018 19:49

Да, при условии, что AllocHiddenConsole возвращает true.

Dark Falcon 10.08.2018 19:51

что может заставить его вернуть ложь?

Mohammed B. 10.08.2018 20:09

Попробовал код в правке - после удаления {} из STARTUPINFO startupInfo {}; PROCESS_INFORMATION processInfo {}; как они выдают ошибку! - Консольное приложение перестает работать: D

Mohammed B. 10.08.2018 21:20

Я исправил это, но, к сожалению, cmd мигает, а затем исчезает :( Я использовал его перед использованием любого _popen - сразу после wmain. Я что-то сделал не так?

Mohammed B. 10.08.2018 21:33

Вы не можете удалить {} и ожидать, что он будет работать так же. Это обнуляет память структуры. Если этот синтаксис недействителен, сделайте это с помощью вызова ZeroMemory или memset.

Dark Falcon 10.08.2018 23:03

Я исправил это, сделав STARTUPINFO startupInfo = {}, но, как я уже сказал, все еще появляется :(

Mohammed B. 11.08.2018 00:22

Хочу добавить, что этот код работал хорошо, когда сам проект был приложением win32, а НЕ консольным приложением, в котором я изменил его подсистему.

Mohammed B. 13.08.2018 17:46

Да, все дело в том, что вам нужно использовать ВСЕ ответ, чтобы это сработало ...

Dark Falcon 13.08.2018 18:16

Другие вопросы по теме