隐藏由 system();调用的命令提示符

Hiding command prompt called by system();

本文关键字:调用 命令提示符 system 隐藏      更新时间:2023-10-16

Goodday,我有脚本,可以循环目录中的所有文件,但是我需要在以这种方式循环它们时隐藏控制台。这是脚本的一部分:

#include <iostream>
#include <fstream>
#include <Windows.h>
using namespace std;
 int GetFilesInDirectory(const char * dir,string dest[],unsigned int max){
    string loc=dir;
    int ctr=0;
    if(loc.length()>2)
        if(loc.substr(loc.length()-2,1)=="\")
            loc=loc.substr(0,loc.length()-1);
    string opcommand;
    string delcommand;
    if(loc.length()>2){
        opcommand="cd "+(loc)+" && dir /s /b /a > tmpfile.cpptmp";
        delcommand="cd "+(loc)+" && del tmpfile.cpptmp";
    } else {
        opcommand="dir /s /b /a > tmpfile.cpptmp";
        delcommand="del tmpfile.cpptmp";
    }
    system(opcommand.c_str());
    ifstream f;
    string line;
    string fileloc;
    if(loc.length()>2)
        fileloc=(loc)+"\tmpfile.cpptmp";
    else fileloc="tmpfile.cpptmp";
    f.open(fileloc,ios::binary);
    while(f.good()){
        getline(f,line);
        if(line.length()>1&&ctr<max){
            dest[ctr]=line;
            ctr++;
        }
    }
    f.close();
    system(delcommand.c_str());
    return ctr;
}
int main() {
    FreeConsole();
    const unsigned int filescountmax=16184;
    string files[filescountmax];
    int count=GetFilesInDirectory("\",files,filescountmax);
    string ext;
    for(int i=0;i<count;i++){
            //some script
    }
}

当进程启动时,它会隐藏它自己,但在它显示 cmd.exe 之后,它会自行关闭它。顺便说一下,我知道还有其他方法可以在目录中循环文件,但这是在子目录和子目录等中循环文件的最简单方法。你能帮帮我吗?

您可以更改子系统以使 Windows 隐藏控制台。在源代码中添加以下命令:

#pragma comment(linker, "/subsystem:"windows" /entry:"mainCRTStartup"" )

或者,您可以使用标志CREATE_NO_WINDOW尝试CreateProcess函数。

这是我为此类任务编写的系统功能的模拟。

int system_hidden(const char *cmdArgs)
{
    PROCESS_INFORMATION pinfo;
    STARTUPINFO sinfo;
    /*
     * Allocate and hide console window
     */
    AllocConsole ();
    ShowWindow (GetConsoleWindow(), 0);
    memset (&sinfo, 0, sizeof (sinfo));
    sinfo.cb = sizeof (sinfo);
    CreateProcess (NULL, (char*)cmdArgs,
                   NULL, NULL, false,
                   0,
                   NULL, NULL, &sinfo, &pinfo);
    DWORD ret;
    while (1)
    {
        HANDLE array[1];
        array[0] = pinfo.hProcess;
        ret = MsgWaitForMultipleObjects (1, array, false, INFINITE,
                                         QS_ALLPOSTMESSAGE);
        if ((ret == WAIT_FAILED) || (ret == WAIT_OBJECT_0))
            break;
        /*
         * Don't block message loop
         */
        MSG msg;
        while (PeekMessage (&msg, 0, 0, 0, PM_REMOVE))
        {
            TranslateMessage (&msg);
            DispatchMessage (&msg);
        }
    }
    DWORD pret;
    GetExitCodeProcess (pinfo.hProcess, &pret);
//    FreeConsole ();
    return pret;
}

我注意到接受的答案有点太复杂了。下面是在没有新cmd.exe窗口的情况下执行命令的更简单方法。基于Roland Rabien和MSDN的回答:

int windows_system(const char *cmd)
{
  PROCESS_INFORMATION p_info;
  STARTUPINFO s_info;
  LPSTR cmdline, programpath;
  memset(&s_info, 0, sizeof(s_info));
  memset(&p_info, 0, sizeof(p_info));
  s_info.cb = sizeof(s_info);
  cmdline     = _tcsdup(TEXT(cmd));
  programpath = _tcsdup(TEXT(cmd));
  if (CreateProcess(programpath, cmdline, NULL, NULL, 0, 0, NULL, NULL, &s_info, &p_info))
  {
    WaitForSingleObject(p_info.hProcess, INFINITE);
    CloseHandle(p_info.hProcess);
    CloseHandle(p_info.hThread);
  }
}

适用于所有Windows平台。像你system()一样打电话。

我使用它,只支持运行块cmd。 比如在destktop中创建shortcat,比如打开记事本.exe编辑文件等等。

#define MAX_SYSTEM_PROGRAM (4096)
static int windows_system(const wchar_t *cmd)
{
    PROCESS_INFORMATION p_info;
    STARTUPINFO s_info;
    DWORD ReturnValue;
    memset(&s_info, 0, sizeof(s_info));
    memset(&p_info, 0, sizeof(p_info));
    s_info.cb = sizeof(s_info);
    wchar_t utf16cmd[MAX_SYSTEM_PROGRAM] = {0};
    MultiByteToWideChar(CP_UTF8, 0, cmd, -1, utf16cmd, MAX_SYSTEM_PROGRAM);
    if (CreateProcessW(NULL, utf16cmd, NULL, NULL, 0, 0, NULL, NULL, &s_info, &p_info))
    {
        WaitForSingleObject(p_info.hProcess, INFINITE);
        GetExitCodeProcess(p_info.hProcess, &ReturnValue);
        CloseHandle(p_info.hProcess);
        CloseHandle(p_info.hThread);
    }
    return ReturnValue;
}