【问题标题】:start a program without a console window (in background)启动没有控制台窗口的程序(在后台)
【发布时间】:2011-06-14 11:42:43
【问题描述】:

我想在 Windows 启动时启动一个简单的程序,但我不想显示与该程序关联的控制台输出窗口。只是为了测试,程序可以很简单:

    int main (int argc, char** argv)
    {
        while (1)
        {
             printf ("hello world...\n");
             Sleep (10000);
        }
    return 0;
    }

编译为:cl foo.c

我知道如何在 windows 启动时启动程序(放入启动文件夹、创建注册表等),但我不知道如何隐藏程序启动时出现的控制台输出窗口。

在搜索这个时,我发现我可以使用start /B foo.exe。有没有其他方法可以做到这一点?像 "&" 这样的东西,我们在 unix 上使用。

我的实际程序很大并且是用C 编写的,所以我不能使用我为c#(如WinMain)和java(如解释here)找到的一些其他替代方案。

【问题讨论】:

  • WinMain 不是 C# 入口点。它用于 C 程序,带有 cl /subsystem:windows 命令行选项。
  • @Marcelo:你会这样回答吗?
  • This 可能会有所帮助。另外对于底层细节检查here

标签: c windows background


【解决方案1】:

WinMain 不是 C# 入口点。 C#使用静态类的方法;默认调用 Main,但可以配置为任何静态类方法。

在 Windows 中,非控制台 C 程序应定义 WinMain。然后,您可以使用链接器的 /subsystem:windows 命令行选项链接它们,可以直接调用或从 CL 调用。

【讨论】:

  • /subsystem:windows 命令行选项与普通的main 不是同样好用并且更便携吗?
  • @rubenvb:不,签名和调用约定不同。
  • 我使用 Eclipse,它为我链接了所有内容,我真的不知道如何更改它,有人可以告诉我怎么做吗?
  • @John:不要通过评论另一个问题的答案来提问。只有@aajtak、@rubenvb 和我可能会看到您的评论,而且可能我们都不知道 Eclipse(我不知道)。自己提出问题,如果相关,请链接到该问题。
  • 使用 /ENTRY 会搞乱 C 运行时初始化。您可能应该删除该位。
【解决方案2】:

这应该可行。

#include <windows.h>

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdParam, int iCmdShow)
{
    for (;;) {
        //action here
    }
    return 0;
}

【讨论】:

  • 请注意,如果您在签名中省略 WINAPI,它将不起作用,我不知道实际上为什么,但我花了 3 个小时才知道这一点,我觉得总有一天有人会发现这很有用跨度>
  • WINAPI__stdcall 的别名,否则将使用默认的__cdecl 调用约定
【解决方案3】:

WinMain 不是 C# 独有的。也可以用 C 编写 GUI 应用程序。 WinMain 函数是入口点,但没有说您必须实际创建一个窗口。您可以让 WinMain 只调用程序的第一个函数来启动它。然后,您的程序将在没有 GUI 窗口和控制台窗口的情况下运行。

当然,这也意味着没有简单的方法来阻止它,除非从任务管理器中杀死它。

【讨论】:

    【解决方案4】:

    一种方法是调用FreeConsole() 作为main 中的第一件事。它将隐藏控制台窗口(如果有)。

    【讨论】:

    • 不幸的是,在 Win 7 上控制台出现了很短的时间
    【解决方案5】:

    不幸的是,简单地将 FreeConsole() 设置为 main 中的第一个函数,无论如何都会让窗口暂时出现。 FreeConsole 会删除该窗口,因此如果您希望稍后使用它(如终止进程),您必须使其以您无法控制的模式出现在屏幕上。

    Windows 允许 Win32 程序在 Visual Studio 下仅具有以下四种上下文之一:带有初始 GUI 窗口的窗口程序、带有初始控制台窗口的控制台程序、DLL 或 Lib。从项目-> 属性-> 系统视图将子系统更改为非控制台选项只会导致阻止构建的链接问题。

    这对我来说只需要一点点努力。使用上面 Mike 的方法并选择 Win32 Project with Window Application。然后在“Place code here”方向之后删除WinMain中的所有内容并删除所有调用的函数。如您所愿,从 WinMain 返回 true 或 1。启动时不会出现任何类型的窗口。

    当您准备好处理代码中的控制台窗口调用 AllocConsole() 并按照您认为合适的方式处理其位置和大小时。如果您愿意,可以将控制台置于屏幕外并滑入视图;只需几分钟即可掌握配置功能。从 Microsoft 在 MSDN 文档中的“控制台功能”开始。不幸的是,没有像 Linux 中的 NCurses 那样正确使用所有功能的书。

    【讨论】:

      【解决方案6】:

      当您创建项目时,请改为使用 WinMain 创建一个( Win32 Project )。如果您以后仍需要控制台,请使用 AllocConsole() 和 FreeConsole()。

      【讨论】:

        【解决方案7】:

        如果程序是 procexp.exe,您可以直接执行此操作:

        cmd /c "start C:\Users\denni\OneDrive\_bin\_tools\ProcessExplorer\procexp.exe"
        

        【讨论】:

          猜你喜欢
          • 2011-01-20
          • 2010-09-08
          • 1970-01-01
          • 1970-01-01
          • 2022-01-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多