win32 GUI 应用程序,当作为“app.exe --help"调用时将使用文本写入标准输出; [英] win32 GUI app that writes usage text to stdout when invoked as "app.exe --help"

查看:28
本文介绍了win32 GUI 应用程序,当作为“app.exe --help"调用时将使用文本写入标准输出;的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何创建执行以下操作的 Windows 应用程序:

How do I create a windows application that does the following:

  • 在没有命令行参数的情况下调用时,它是一个常规的 GUI 应用
  • 指定可选的--help"命令行参数会导致应用将使用文本写入标准输出然后终止
  • 它必须是单个可执行文件.通过将控制台应用程序 exec 设置为第二个可执行文件,不会作弊.
  • 假设主要应用程序代码是用 C/C++ 编写的
  • 如果在指定--help"时没有创建 GUI 窗口,则加分.(即,没有来自短暂窗口的闪烁)

根据我的经验,控制台应用程序的标准 Visual Studio 模板没有 GUI 功能,普通的 win32 模板不会将其标准输出发送到父 cmd shell.

In my experience the standard visual studio template for console app has no GUI capability, and the normal win32 template does not send its stdout to the parent cmd shell.

推荐答案

Microsoft 设计的控制台和 GUI 应用程序是相互排斥的.这一点短视意味着没有完美的解决方案.最流行的方法是有两个可执行文件(例如 cscript/wscript,java/javaw、devenv.com/devenv.exe 等)但是你已经表明你认为这是作弊".

Microsoft designed console and GUI apps to be mutually exclusive. This bit of short-sightedness means that there is no perfect solution. The most popular approach is to have two executables (eg. cscript / wscript, java / javaw, devenv.com / devenv.exe etc) however you've indicated that you consider this "cheating".

您有两个选择 - 制作控制台可执行文件"或gui 可执行文件",然后使用代码尝试提供其他行为.

You've got two options - to make a "console executable" or a "gui executable", and then use code to try to provide the other behaviour.

  • GUI 可执行文件:

cmd.exe 将假定您的程序没有控制台 I/O,因此不会等待它终止在继续之前,这在交互模式下(即不是批处理)意味着显示下一个 ("C:\>") 提示并从键盘读取.因此,即使您使用 AttachConsole,您的输出也会混合cmd 的输出,如果你尝试输入,情况会变得更糟.这基本上是一个非启动器.

cmd.exe will assume that your program does no console I/O so won't wait for it to terminate before continuing, which in interactive mode (ie not a batch) means displaying the next ("C:\>") prompt and reading from the keyboard. So even if you use AttachConsole your output will be mixed with cmd's output, and the situation gets worse if you try to do input. This is basically a non-starter.

  • 控制台可执行文件:

与信念相反,没有什么可以阻止控制台可执行文件显示 GUI,但有两个问题.

Contrary to belief, there is nothing to stop a console executable from displaying a GUI, but there are two problems.

第一个是,如果你从没有参数的命令行运行它(所以你想要 GUI),cmd 仍然会等待它终止才能继续,所以特定的控制台在此期间将无法使用.这可以通过启动来克服同一可执行文件的第二个进程(你认为这是作弊吗?),将 DETACHED_PROCESS 标志传递给 CreateProcess() 并立即退出.然后新进程可以检测到它没有控制台并显示 GUI.

The first is that if you run it from the command line with no arguments (so you want the GUI), cmd will still wait for it to terminate before continuing, so that particular console will be unusable for the duration. This can be overcome by launching a second process of the same executable (do you consider this cheating?), passing the DETACHED_PROCESS flag to CreateProcess() and immediately exiting. The new process can then detect that it has no console and display the GUI.

以下是用于说明此方法的 C 代码:

Here's C code to illustrate this approach:

#include <stdio.h>
#include <windows.h>

int main(int argc, char *argv[])
{
    if (GetStdHandle(STD_OUTPUT_HANDLE) == 0) // no console, we must be the child process
    {
        MessageBox(0, "Hello GUI world!", "", 0);
    }
    else if (argc > 1) // we have command line args
    {
        printf("Hello console world!\n");
    }
    else // no command line args but a console - launch child process
    {
        DWORD dwCreationFlags = CREATE_DEFAULT_ERROR_MODE | DETACHED_PROCESS;
        STARTUPINFO startinfo;
        PROCESS_INFORMATION procinfo;
        ZeroMemory(&startinfo, sizeof(startinfo));
        startinfo.cb = sizeof(startinfo);
        if (!CreateProcess(NULL, argv[0], NULL, NULL, FALSE, dwCreationFlags, NULL, NULL, &startinfo, &procinfo))
            MessageBox(0, "CreateProcess() failed :(", "", 0);
    }
    exit(0);
}

我用 cygwin 的 gcc - YMMV 和 MSVC 编译它.

I compiled it with cygwin's gcc - YMMV with MSVC.

第二个问题是,当从资源管理器运行时,你的程序会在一瞬间显示控制台窗口.没有编程方式解决这个问题,因为控制台是由 Windows 在应用启动时创建,然后才开始执行.你唯一能做的做的是,在您的安装程序中,使用显示命令"创建程序的快捷方式SW_HIDE(即0).这只会影响控制台,除非您故意尊重 STARTUPINFO 的 wShowWindow 字段在你的程序中,所以不要这样做.

The second problem is that when run from Explorer, your program will for a split second display a console window. There's no programmatic way around this because the console is created by Windows when the app is launched, before it starts executing. The only thing you can do is, in your installer, make the shortcut to your program with a "show command" of SW_HIDE (ie. 0). This will only affect the console unless you deliberately honour the wShowWindow field of STARTUPINFO in your program, so don't do that.

我通过破解 cygwin 的mkshortcut.exe"对此进行了测试.你如何完成它在您选择的安装程序中由您决定.

I've tested this by hacking cygwin's "mkshortcut.exe". How you accomplish it in your install program of choice is up to you.

当然,用户仍然可以通过在资源管理器中找到可执行文件来运行您的程序,然后双击它,绕过隐藏控制台的快捷方式并看到控制台窗口的短暂黑色闪光.对此你无能为力.

The user can still of course run your program by finding the executable in Explorer and double-clicking it, bypassing the console-hiding shortcut and seeing the brief black flash of a console window. There's nothing you can do about it.

这篇关于win32 GUI 应用程序,当作为“app.exe --help"调用时将使用文本写入标准输出;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆