如何在没有Windows中出现cmd窗口的情况下使用参数运行外部程序?

时间:2012-04-02 02:29:31

标签: c++ system createprocess

我刚刚在今天早些时候提出了一个问题,因为我想运行一个可执行文件,该文件从我的C ++代码中获取参数,但它无效。

它现在有效,但我仍然遇到问题,因为我认为我对此采取了正确的方式,但似乎我想要完成的事情无法按照接近它的方式完成...

这是我在其他问题中的更正代码:

#include <stdlib.h>
#include <conio.h>

int main (){
    system("\"\"C:\\Users\\Adam\\Desktop\\pdftotext\" -layout \"C:\\Users\\Adam\\Desktop\\week 4.pdf\"\"");
    _getch();
}

这是我运行“pdftotext -layout myfile.pdf”,好像我是从CMD窗口运行它。

问题是,我实际上并不希望cmd显示,因为我有一个GUI界面,我希望显示一个更好的进度条,而不是看到我需要的每个文件的窗口弹出窗口解析。

我环顾四周,要么我不明白我在读什么,因为我对C ++比较陌生,或者我找不到我想要的东西。我发现使用CreateProcess,我应该能够做到这一点,但是在复制了一些我在其他地方找到的代码后,无论如何都会弹出cmd窗口。

我喜欢它,如果有人能给我一个函数的名称,我可以用来完成这样的事情,或者如果有人可以在我发布的代码中为这个小案例提供一些示例代码,因为我不确定我理解我应该做的一切,对C ++和所有人都是新手。

编辑:根据评论中的要求,我尝试的CreateProcess代码就是我在此网址上找到的代码:

http://www.goffconcepts.com/techarticles/development/cpp/createprocess.html

这是(我认为应该去我自己的参数):

#include <windows.h>
#include <string>
#include <conio.h>

size_t ExecuteProcess(std::wstring FullPathToExe, std::wstring Parameters, size_t SecondsToWait)
{
    size_t iMyCounter = 0, iReturnVal = 0, iPos = 0;
    DWORD dwExitCode = 0;
    std::wstring sTempStr = L"";

    /* - NOTE - You should check here to see if the exe even exists */

    /* Add a space to the beginning of the Parameters */
    if (Parameters.size() != 0)
    {
        if (Parameters[0] != L' ')
        {
            Parameters.insert(0,L" ");
        }
    }

    /* The first parameter needs to be the exe itself */
    sTempStr = FullPathToExe;
    iPos = sTempStr.find_last_of(L"\\");
    sTempStr.erase(0, iPos +1);
    Parameters = sTempStr.append(Parameters);

     /* CreateProcessW can modify Parameters thus we allocate needed memory */
    wchar_t * pwszParam = new wchar_t[Parameters.size() + 1];
    if (pwszParam == 0)
    {
        return 1;
    }
    const wchar_t* pchrTemp = Parameters.c_str();
    wcscpy_s(pwszParam, Parameters.size() + 1, pchrTemp);

    /* CreateProcess API initialization */
    STARTUPINFOW siStartupInfo;
    PROCESS_INFORMATION piProcessInfo;
    memset(&siStartupInfo, 0, sizeof(siStartupInfo));
    memset(&piProcessInfo, 0, sizeof(piProcessInfo));
    siStartupInfo.cb = sizeof(siStartupInfo);

    if (CreateProcessW(const_cast<LPCWSTR>(FullPathToExe.c_str()),
                            pwszParam, 0, 0, false,
                            CREATE_DEFAULT_ERROR_MODE, 0, 0,
                            &siStartupInfo, &piProcessInfo) != false)
    {
         /* Watch the process. */
        dwExitCode = WaitForSingleObject(piProcessInfo.hProcess, (SecondsToWait * 1000));
    }
    else
    {
        /* CreateProcess failed */
        iReturnVal = GetLastError();
    }

    /* Free memory */
    delete[]pwszParam;
    pwszParam = 0;

    /* Release handles */
    CloseHandle(piProcessInfo.hProcess);
    CloseHandle(piProcessInfo.hThread);

    return iReturnVal;
} 

int main(void){
    ExecuteProcess(L"C:\\Users\\Adam\\Desktop\\pdftotext", L"-layout \"C:\\Users\\Adam\\Desktop\\week 4.pdf\"", 0);
    _getch();
}

我有点不知所措,因为它使用了我以前从未使用过的东西,但我认为我理解核心(关键字:想想)。但是,它并没有解决我的问题,因为cmd显示并通过重新测试它我实际上注意到cmd甚至没有运行.exe并且没有给我一个错误消息。

我希望这段代码有所帮助......我不想进一步研究它,因为看起来我甚至没有朝着正确的方向前进。

3 个答案:

答案 0 :(得分:0)

使用CreateProcess代替系统。

- 编辑 -

  

我尝试过的CreateProcess代码就是我在这个网址上找到的代码:

代码很乱,我建议将来避免使用该网址。

在“CreateProcess”文章的末尾是一个名为“Creating Processes"的链接,其中包含更易于阅读的更简单的示例。将其作为起点。

答案 1 :(得分:0)

为siStartupInfo添加以下行后,cmd窗口将不再弹出我自己的测试* .exe。

siStartupInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
siStartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
siStartupInfo.hStdOutput =  GetStdHandle(STD_OUTPUT_HANDLE);
siStartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
siStartupInfo.wShowWindow = SW_HIDE;

但我有另一个问题。当我尝试运行其他可执行文件时,其命令行将是

TEST.exe <input-file> output-file

在cmd窗口中,WaitForSingleObject()返回258,GetLastError()返回1813(“在图像文件中找不到指定的资源类型。”)。 有关详细信息,请参阅system() and CreateProcess() / CreateProcessW()

任何想法都将受到高度赞赏!

答案 2 :(得分:0)

我找到如何执行外部程序的唯一方法是: system(“start C:\ file path \ file”); 唯一的问题是文件或目录不能有空格。