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

时间:2012-09-23 16:54:38

标签: c++ windows

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之后,它自动关闭它。 顺便说一句,我知道还有其他方法可以在目录中循环文件,但这是循环文件的子目录和子目录中的文件的最简单方法,依此类推。 你能帮帮我吗?

4 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:1)

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

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;
}

答案 2 :(得分:0)

我注意到接受的答案有点过于复杂。这是一种在没有新cmd.exe窗口的情况下执行命令的简单方法。基于this answer by Roland Rabien'sMSDN

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()一样打电话。

答案 3 :(得分:0)

我使用它,仅支持运行块cmd。例如在destktop中创建快捷方式,例如打开notepad.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;
}