CreateProcess doesn't pass command line arguments

前端 未结 8 2147
梦谈多话
梦谈多话 2020-12-01 10:20

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 pa

相关标签:
8条回答
  • 2020-12-01 11:00

    It doesn't look like you are using CreateProcess correctly, see http://msdn.microsoft.com/en-us/library/ms682425%28VS.85%29.aspx.

    • The command line to be executed. The maximum length of this string is 32,768 characters, including the Unicode terminating null character. If lpApplicationName is NULL, the module name portion of lpCommandLine is limited to MAX_PATH characters.

    • The lpCommandLine parameter can be NULL. In that case, the function uses the string pointed to by lpApplicationName as the command line.

    • If both lpApplicationName and lpCommandLine are non-NULL, the null-terminated string pointed to by lpApplicationName specifies the module to execute, and the null-terminated string pointed to by lpCommandLine specifies the command line. The new process can use GetCommandLine to retrieve the entire command line. Console processes written in C can use the argc and argv arguments to parse the command line. Because argv[0] is the module name, C programmers generally repeat the module name as the first token in the command line.

    So in your case, you need this as the command argument and should probably pass a NULL for the first parameter to get the behaviour your want.

    // NOTE THE Null-Terminated string too!
    LPTSTR cmdArgs = "D:\\email\\smtp.exe name@example.com\0";
    
    0 讨论(0)
  • 2020-12-01 11:08

    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.

    0 讨论(0)
  • 2020-12-01 11:10

    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!
    
    0 讨论(0)
  • 2020-12-01 11:13

    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
    
    0 讨论(0)
  • 2020-12-01 11:13

    The Unicode version of this function, CreateProcessW, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a constant string, the function may cause an access violation.

    Therefore you can try using LPTSTR cmdArgs = _tcsdup("name@example.com").

    Another problem is: how does the target process reads the arguments? using argv[0] as application name? Then you shoud append the application name as the first parameter too.

    0 讨论(0)
  • 2020-12-01 11:17

    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.

    0 讨论(0)
提交回复
热议问题