【问题标题】:Create an Application without a Window创建没有窗口的应用程序
【发布时间】:2010-09-18 11:05:55
【问题描述】:

您将如何编写一个无需打开窗口或控制台即可运行的 C/C++ 应用程序?

【问题讨论】:

标签: c++ c winapi


【解决方案1】:

当您编写 WinMain 程序时,您会自动将 /SUBSYSTEM 选项设置为编译器中的窗口。 (假设您使用 Visual Studio)。对于任何其他编译器,可能存在类似的选项,但标志名称可能不同。

这会导致编译器以可执行文件格式 (PE format) 创建一个条目,将可执行文件标记为 Windows 可执行文件。

一旦此信息出现在可执行文件中,启动程序的系统加载程序会将您的二进制文件视为 Windows 可执行文件而不是控制台程序,因此它不会导致控制台窗口在运行时自动打开。

但是如果不需要,Windows 程序不需要创建任何窗口,就像您看到在任务栏中运行的所有那些程序和服务一样,但看不到它们的任何相应窗口。如果您创建一个窗口但选择不显示它,也会发生这种情况。

为了实现这一切,你需要做的就是,

#include <Windows.h>

int WinMain(HINSTANCE hInstance,
            HINSTANCE hPrevInstance, 
            LPTSTR    lpCmdLine, 
            int       cmdShow)
    {
    /* do your stuff here. If you return from this function the program ends */
    }

您需要 WinMain 本身的原因是,一旦您将子系统标记为 Windows,链接器会假定您的入口点函数(在程序加载和 C Run TIme 库初始化后调用)将是 WinMain 而不是 main .如果您在此类程序中未提供 WinMain,您将在链接过程中收到未解决的符号错误。

【讨论】:

  • 我有类似的要求,我使用计时器。我希望程序不间断地运行。在这个程序中,已经设置了一个计时器。那我该怎么做。 ?
  • 不应该是int WINAPI WinMain(...)吗?
  • Visual Studio 2017 中的实际待办事项,例如:1) 打开 Visual Studio 2) File->New->Project 3) Visual C++ -> General 4) 选择 Empty Project 5) 剪切并粘贴上面的sn-p。添加睡眠(60000);所以那个程序会等你。编译程序生成program.exe。双击 program.exe,程序会保持活动状态 60 秒。检查任务管理器并在那里查看 program.exe。
【解决方案2】:

在 Windows 中:

#include <windows.h>

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
    // <-- Program logic here
    return 0;
}   

请务必使用 Adam Mitz 提到的 /SUBSYSTEM 链接器开关。

在其他平台上:

int main(int argc, char**argv)
{
  // <-- Program logic here
  return 0;
}

【讨论】:

  • 两个抱怨:如果不包含 windows.h,WinMain 是不必要的;并返回 0;在 main 中是可选的。
  • 你想返回 0,这样你就可以对调用它的程序表示成功。
  • 如果你制作了一个控制台应用程序并且有 int main for windows,当你双击 exe 时,你会弹出一个控制台窗口。
  • 我认为这实际上是 /SUBSYSTEM 链接器开关,用于确定是否存在控制台窗口。
  • @Brian - 如果没有指定返回值,main() 默认返回 0。这是一个疯狂的特例,只适用于 main()。
【解决方案3】:

如果您需要在没有控制台或窗口的情况下连续运行您的程序,您可能会发现有用的 deamon on *NIXservices on Windows,如果您需要普通的 win32,这个 .NET 示例只需在谷歌上搜索一下即可。
由于您的问题标记为 win32,因此我认为服务与您更相关。

【讨论】:

    【解决方案4】:

    这也处理消息:

    #include <windows.h>
    #include <stdio.h>
    
    int CALLBACK WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
        MSG msg;
        DWORD curThreadId;
    
        curThreadId = GetCurrentThreadId();
    
        // Send messages to self:
        PostThreadMessage(curThreadId, WM_USER, 1, 2);
        PostThreadMessage(curThreadId, WM_USER+1, 3, 4);
        PostThreadMessage(curThreadId, WM_USER+2, 5, 6);
        PostThreadMessage(curThreadId, WM_USER+3, 7, 8);
        PostThreadMessage(curThreadId, WM_QUIT, 9, 10);
    
        while (GetMessage(&msg, NULL, 0, 0)) {
            printf("message: %d; wParam: %d; lParam: %d\n", msg.message, msg.wParam, msg.lParam);
        }
    
        return (int) msg.wParam;
    } 
    

    【讨论】:

    • 谢谢。在这种情况下,printf 输出在哪里?
    【解决方案5】:

    在 Visual Studio Express 2010 中,将子系统设置为 windows 后(如 user17224 所建议),或者将 main 更改为 WinMain(如 user17224 和 Brian R. Bondy 所建议),可以在属性中将入口函数设置为 main 、链接器、高级、入口点:只需在文本框中键入 main。

    【讨论】:

    • 我在 Visual Studio 2017 中尝试了“main”,并使用了 /SUBSYSTEM liker 选项的每种组合,但无济于事。但是,我发现这里的答案是“WinMain”入口点而不是“main”。
    【解决方案6】:

    使用 Visual Studio 向导创建 Win32 应用程序。但不要创建窗口,即删除窗口创建功能。 或者,我们可以创建 Win Service 应用程序。

    【讨论】:

      【解决方案7】:

      如果您使用的是 MSVCVisual Studio,只需使用新的 Project Wizard 并选择 Console Application .

      【讨论】:

      • 控制台应用程序在运行时总是会打开一个控制台窗口
      • 你确定你知道你在说什么吗? en.wikipedia.org/wiki/Win32_console我觉得不行!!!上次我看一个控制台应用程序是一个非 gui win32 应用程序!!!
      • jussij - 正确。这是一个 CLUI 应用程序。为了与那个 CLUI 交互,windows 会为你创建一个 CL GUI。
      • @jussji - 你是对的 - 控制台程序没有任何“窗口”,但尝试从资源管理器中双击控制台程序,操作系统将自动创建一个控制台窗口来运行控制台程序。 Op 似乎既不需要真正的窗口,也不需要控制台。因此我的评论。
      • 可以禁止创建窗口!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多