CreateProcess doesn't pass command line argume

2019-01-09 14:27发布

Hello I have the following code but it isn't working as expected, can't figure out what the problem is.

Basically, I'm executing a process (a .NET process) and passing it command line arguments, it is executed successfully by CreateProcess() but CreateProcess() isn't passing the command line arguments

What am I doing wrong here??

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

EDIT: Hey one more thing, if I pass my cmdArgs like this:

// a space as the first character
LPTSTR cmdArgs = " name@example.com";

Then I get the error, then CreateProcess returns TRUE but my target process isn't executed.

Object reference not set to an instance of an object

8条回答
爷的心禁止访问
2楼-- · 2019-01-09 14:57

If the first parameter to CreateProcess() is non-NULL, it will use that to locate the image to launch.

If it is NULL, it will parser the 2nd argument to try to get the executable to launch from the 1st token.

In either case, the C runtime will use the second argument to populate the argv array. So the first token from that parameter shows up in argv[0].

You probably want something like the following (I've change the smtp.exe program to echoargs.exe - a simple utility I have to help figure out just this kind of issue):

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

Here's the output I get from that program:

echoargs.exe name@example.com
[0]: echoargs.exe
[1]: name@example.com

Yohoo!
查看更多
地球回转人心会变
3楼-- · 2019-01-09 14:58

You should specify also the module name in parameters: LPTSTR cmdArgs = "App name@example.com"; It should be the whole command line (including argv[0]).

查看更多
地球回转人心会变
4楼-- · 2019-01-09 15:03

You are not allocating memory for your string.

Instead of:

LPTSTR cmdArgs = "name@example.com";

try:

TCHAR cmdArgs[] = "name@example.com";

Edit: then call:

 CreateProcess("D:\\email\\smtp.exe", &cmdArgs[0], ...

This will create a local array on the stack and then pass a pointer to that array.

查看更多
我想做一个坏孩纸
5楼-- · 2019-01-09 15:04

You can add a space as first character of the cmdArgs string:

LPTSTR cmdArgs = " name@example.com";

Apparently Windows appends the 2nd argument string to the application name represented by the first argument, and the result is passed as command line arguments to the executable. So adding a space will properly separate the arguments.

查看更多
相关推荐>>
6楼-- · 2019-01-09 15:12

Try this:

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
查看更多
在下西门庆
7楼-- · 2019-01-09 15:13

Below is a cut down version of the code used by the Zeus IDE to run external processes:

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

The pszCommand would be the full executable path and file name and arguments so for example:

pszCommand = "D:\\email\\smtp.exe name@example.com";

From what I can tell, the only real difference between the two is that in the Zeus example, the dwCreationFlags argument is set to the CREATE_NEW_PROCESS_GROUP value.

查看更多
登录 后发表回答