当我们运行 .bat 文件,或者用其他软件调用 cmd /c ... 时,cmd 窗口会一闪而过(或者停留一阵,如果运行时间较长),有些时候非常碍眼。有很多方法可以隐藏这个 cmd 窗口,比如用各种语言调用 WScript.Shell 的 Run 函数,用 AHK 的 Run 函数,还有不少 SilentCMDhide-win32-console-window 之类的工具。但这些方法都比较慢,一般需要 30 毫秒以上(之后发现还是有快的,NirCmdexecmd 能在 10 毫秒多完成,但用的是 CreateProcessA)。写不好的话,空格、引号、括号、字符集之类地方还会出问题。

其实用 C 语言实现这个功能很简单,耗时也在 10 毫秒之内。

wrun.c:

#include <windows.h>

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) {
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    CreateProcessW(NULL, lpCmdLine, NULL, NULL, 0, CREATE_NO_WINDOW, NULL, NULL, &si, &pi);

    return 0;
}

lpCmdLine 是不包含程序自身名称的参数字符串,会自行处理好空格、引号等麻烦事,可以直接传递给 CreateProcessW,非常方便。另外注意如果用 CreateProcessA 的话,一般情况也能正常使用(wWinMain 要改成 WinMain,LPWSTR lpCmdLine 改成 LPSTR lpCmdLine,编译时去掉 -municode),但如果文件名包含 emoji 等本地语言编码(Windows 简体中文版是 GBK)无法表示的字符,就会失败,所以最好用 CreateProcessW。

用 MinGW 编译:

gcc -O2 wrun.c -mwindows -municode -o wrun.exe

# 缩小体积,可选
strip wrun.exe

也可以用 VS 编译,创建一个 Windows 桌面应用程序,把主文件代码替换成它即可。

使用方法:

wrun cmd /c md "测试 目录"
wrun cmd /c (if not exist "目录 '1" md "目录 '1")
wrun test.bat