aki*_*kif 26 c++ winapi createprocess
您好我有以下代码,但它没有按预期工作,无法弄清楚问题是什么.
基本上,我正在执行一个进程(一个.NET进程)并传递它的命令行参数,它由CreateProcess()成功执行但CreateProcess()没有传递命令行参数
我在这做错了什么?
int main(int argc, char* argv[])
{
PROCESS_INFORMATION ProcessInfo; //This is what we get as an [out] parameter
STARTUPINFO StartupInfo; //This is an [in] parameter
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = sizeof StartupInfo ; //Only compulsory field
LPTSTR cmdArgs = "name@example.com";
if(CreateProcess("D:\\email\\smtp.exe", cmdArgs,
NULL,NULL,FALSE,0,NULL,
NULL,&StartupInfo,&ProcessInfo))
{
WaitForSingleObject(ProcessInfo.hProcess,INFINITE);
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
printf("Yohoo!");
}
else
{
printf("The process could not be started...");
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编辑:嘿,还有一件事,如果我这样通过我cmdArgs:
// a space as the first character
LPTSTR cmdArgs = " name@example.com";
Run Code Online (Sandbox Code Playgroud)
然后我得到错误,然后CreateProcess返回TRUE但我的目标进程没有执行.
Object reference not set to an instance of an object
Run Code Online (Sandbox Code Playgroud)
EFr*_*aim 24
应该指定也在参数模块名称:LPTSTR cmdArgs = "App name@example.com";
它应该是整个命令行(包括的argv [0]).
Mic*_*urr 19
如果第一个参数CreateProcess()为非NULL,它将使用它来定位要启动的图像.
如果它为NULL,它将解析第二个参数以尝试从第一个令牌启动可执行文件.
在任何一种情况下,C运行时都将使用第二个参数来填充argv数组.所以该参数的第一个标记出现在argv[0].
您可能需要以下内容(我已将smtp.exe程序更改为echoargs.exe - 一个简单的实用程序,我必须帮助弄清楚这种问题):
int main(int argc, char* argv[])
{
PROCESS_INFORMATION ProcessInfo; //This is what we get as an [out] parameter
STARTUPINFO StartupInfo; //This is an [in] parameter
char cmdArgs[] = "echoargs.exe name@example.com";
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = sizeof StartupInfo ; //Only compulsory field
if(CreateProcess("C:\\util\\echoargs.exe", cmdArgs,
NULL,NULL,FALSE,0,NULL,
NULL,&StartupInfo,&ProcessInfo))
{
WaitForSingleObject(ProcessInfo.hProcess,INFINITE);
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
printf("Yohoo!");
}
else
{
printf("The process could not be started...");
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是我从该程序得到的输出:
echoargs.exe name@example.com
[0]: echoargs.exe
[1]: name@example.com
Yohoo!
Run Code Online (Sandbox Code Playgroud)
看起来您没有正确使用CreateProcess,请参阅http://msdn.microsoft.com/en-us/library/ms682425%28VS.85%29.aspx.
要执行的命令行.此字符串的最大长度为32,768个字符,包括Unicode终止空字符.如果lpApplicationName为NULL,则lpCommandLine的模块名称部分限制为MAX_PATH字符.
lpCommandLine参数可以为NULL.在这种情况下,该函数使用lpApplicationName指向的字符串作为命令行.
如果lpApplicationName和lpCommandLine都是非NULL,则lpApplicationName指向的以null结尾的字符串指定要执行的模块,lpCommandLine指向的以null结尾的字符串指定命令行.新进程可以使用GetCommandLine来检索整个命令行.用C编写的控制台进程可以使用argc和argv参数来解析命令行.因为argv [0]是模块名称,所以C程序员通常会重复模块名称作为命令行中的第一个标记.
所以在你的情况下,你需要这个作为命令参数,并且应该为第一个参数传递NULL以获得你想要的行为.
// NOTE THE Null-Terminated string too!
LPTSTR cmdArgs = "D:\\email\\smtp.exe name@example.com\0";
Run Code Online (Sandbox Code Playgroud)
以下是Zeus IDE用于运行外部进程的代码的简化版本:
bool createProcess(const char *pszTitle, const char *pszCommand)
{
STARTUPINFO StartInfo;
memset(&StartInfo, 0, sizeof(StartInfo));
StartInfo.cb = sizeof(StartInfo);
StartInfo.lpTitle = (pszTitle) ? (char *)pszTitle : (char *)pszCommand;
StartInfo.wShowWindow = SW_NORMAL;
StartInfo.dwFlags |= STARTF_USESHOWWINDOW;
if (CreateProcess(0, (char *)pszCommand,
0, 0, TRUE,
CREATE_NEW_PROCESS_GROUP, 0, 0,
&StartInfo, &ProcessInfo))
{
lErrorCode = 0;
}
else
{
lErrorCode = GetLastError();
}
return (lErrorCode == 0);
}
Run Code Online (Sandbox Code Playgroud)
该pszCommand将是完整的可执行文件的路径和文件名和参数,以便例如:
pszCommand = "D:\\email\\smtp.exe name@example.com";
Run Code Online (Sandbox Code Playgroud)
据我所知,两者之间唯一真正的区别是,在Zeus示例中,dwCreationFlags参数设置为CREATE_NEW_PROCESS_GROUP值.
尝试这个:
LPTSTR cmdArgs = "name@example.com";
CString szcmdline("D:\\email\\smtp.exe");
szcmdline += _T(" ") + cmdArgs ;
//Leave first param empty and pass path + argms in
if(CreateProcess(NULL, szcmdline, second
Run Code Online (Sandbox Code Playgroud)