使用CreateProcess()时Visual C ++不需要的结果

时间:2014-07-08 03:57:56

标签: visual-c++

我正在构建一个Visual C ++控制台应用程序,我需要执行与控制台应用程序位于同一目录中的另一个程序。我使用CreateProcess()来启动它。

VOID startup(LPCTSTR lpApplicationName, LPSTR args)
{
    // additional information
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    // set the size of the structures
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    // start the program up
    CreateProcess(lpApplicationName,   // the path
        args,        // Command line
        NULL,           // Process handle not inheritable
        NULL,           // Thread handle not inheritable
        FALSE,          // Set handle inheritance to FALSE
        0,              // No creation flags
        NULL,           // Use parent's environment block
        NULL,           // Use parent's starting directory 
        &si,            // Pointer to STARTUPINFO structure
        &pi           // Pointer to PROCESS_INFORMATION structure
        );

    WaitForSingleObject(pi.hProcess, INFINITE);

    CloseHandle(pi.hProcess);       // Close process and thread handles. 
    CloseHandle(pi.hThread);
}

这是函数调用 -

string command = "C:\\Users\\username\\Documents\\Visual Studio 2013\\Projects\\Project\\Debug\\potrace.exe"; //the program to be executed
string arg = "-s -o \"" + libraryDir + "\\" + outputFileName + "\" -- \"" + tempDir + "\\" + tempFileName + "\""; //program arguments to be sent

char *args = new char[200];

for (int i = 0; args[i] = arg[i]; ++i); //converting std::string to char*

startup(command.c_str(), args);

问题是当从控制台应用程序中调用并从命令提示符调用时,被调用的程序会产生不同的结果。它生成了一个svg文件但是从应用程序调用时,这个生成的文件已损坏。如果我复制char *args的值并在命令提示符处将其用作参数,则输出文件完美无缺。

更新:在打开生成的文件时,我注意到它是和EPS文件,而不是SVG文件。这很奇怪,因为-s中的args用于生成SVG文件。此外,复制command.c_str()args的值并从命令提示符执行会产生有效的SVG图像。那么为什么同样的命令在调用usign CreateProcess()和命令提示符时产生不同的结果?

更新:如果我修改args以包含程序名称,即potrace.exe <arguments>并使用startup(NULL, args)调用启动,则它会完美运行。但我仍然想知道原方法中的问题。

1 个答案:

答案 0 :(得分:2)

The documentation for CreateProcess说:

  

如果lpApplicationNamelpCommandLine都是非NULL,则lpApplicationName指向的以null结尾的字符串指定要执行的模块,以及以null结尾的字符串lpCommandLine指向的命令行。

     

新进程可以使用GetCommandLine来检索整个命令行。用C编写的控制台进程可以使用argcargv参数来解析命令行。因为argv[0]是模块名称,所以C程序员通常会重复模块名称作为命令行中的第一个标记。

当C或C ++程序启动时,运行时调用GetCommandLine以获取用于调用程序的命令行。对此进行解析以获取要传递给argc的{​​{1}}和argv

如果正在生成的程序要求程序名称在main中且“实际”参数以argv[0]开头,则必须确保在{{1}中包含程序名称}传递给argv[1],以便它出现在lpCommandLine在生成的进程中返回的命令行字符串中。