我正在构建一个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)
调用启动,则它会完美运行。但我仍然想知道原方法中的问题。
答案 0 :(得分:2)
The documentation for CreateProcess
说:
如果
lpApplicationName
和lpCommandLine
都是非NULL
,则lpApplicationName
指向的以null结尾的字符串指定要执行的模块,以及以null结尾的字符串lpCommandLine
指向的命令行。新进程可以使用
GetCommandLine
来检索整个命令行。用C编写的控制台进程可以使用argc
和argv
参数来解析命令行。因为argv[0]
是模块名称,所以C程序员通常会重复模块名称作为命令行中的第一个标记。
当C或C ++程序启动时,运行时调用GetCommandLine
以获取用于调用程序的命令行。对此进行解析以获取要传递给argc
的{{1}}和argv
。
如果正在生成的程序要求程序名称在main
中且“实际”参数以argv[0]
开头,则必须确保在{{1}中包含程序名称}传递给argv[1]
,以便它出现在lpCommandLine
在生成的进程中返回的命令行字符串中。