【问题标题】:Console Application Console window - Visual C++控制台应用程序控制台窗口 - Visual C++
【发布时间】:2019-01-18 02:56:59
【问题描述】:

我在 Visual Studio 中编写了 C++ 代码,这是一个控制台应用程序。我的问题是如何让最终的 exe 在没有控制台的情况下运行(只能从任务管理器看到的进程)

到目前为止我看到的解决方案都是让控制台出现一秒钟然后熄灭。我不想要这个。根本不出现。

Visual Studio 中是否有任何选项或标志可以执行此操作? (类似于 g++ 中的 -mwindows 标志)

提前致谢

【问题讨论】:

    标签: c++ visual-studio console-application


    【解决方案1】:

    Configuration Properties->Linker->System页面的Project Properties中,需要将SubSystem的值设置为Windows (/SUBSYSTEM:WINDOWS)。新控制台应用程序项目的默认值为Console (/SUBSYSTEM:CONSOLE),这会导致 Windows 在启动程序时分配新控制台或附加到父进程的控制台。


    您还需要将main 函数更改为WinMain。 `WinMain 的签名是:

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

    使用上述方法,子控制台进程仍将创建控制台窗口。由于您在评论中声明要使用popen,因此您不能真正轻松地使用CreateProcessSW_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()。
    • 我得到的WinMain函数不能重载
    • @HansPassant:谢谢,我忘记了这一点,因为我通常使用 C# 执行此操作,其中 Main 的签名不会在各种应用程序类型之间更改。
    • 这会使许多控制台窗口出现、闪烁和消失。他们仍然出现
    • 让我猜猜:您的程序启动了其他也是控制台应用程序的程序?这是唯一能想到的解释。如果没有有关您的程序功能的更多详细信息,我无法确定如何修复它。
    猜你喜欢
    • 2010-12-19
    • 2011-04-20
    • 2014-02-17
    • 2011-04-04
    • 1970-01-01
    • 2022-01-27
    • 1970-01-01
    相关资源
    最近更新 更多