Search code examples
c++winapicreateprocess

c++ can't pass an argument with CreateProcess


i have to pass a string into my process, but for some reason i can't

i've tried to pass a path and an argument in function, i've tried to put a \0 after the argument, i've tried to pass an argument or space + an argument but it doesn't passes. could you please help me?

#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <string>
using namespace std;
void _tmain(int argc, TCHAR* argv[])
{
    cout << "we are here!\n";
    STARTUPINFO si;
    PROCESS_INFORMATION pi;


    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    string first = "C:\\Users\\User\\source\\repos\\1\\x64\\Debug\\1.exe";  //Initializing a name of our file
    wstring temp = wstring(first.begin(), first.end());  // Initializing an object of wstring
    LPCWSTR file_name = temp.c_str();  // Applying c_str() method on temp

    string s1 = " 1.exe 1\0";
    LPWSTR cl1 = (LPWSTR)s1.c_str();

    // Start the child process. 
    if (!CreateProcess(file_name,   // No module name (use command line)
        cl1,        // Command line
        NULL,           // Process handle not inheritable
        NULL,           // Thread handle not inheritable
        FALSE,          // Set handle inheritance to FALSE
        CREATE_NEW_CONSOLE,              // Creating console for our application
        NULL,           // Use parent's environment block
        NULL,           // Use parent's starting directory 
        &si,            // Pointer to STARTUPINFO structure
        &pi)           // Pointer to PROCESS_INFORMATION structure
        )
    {
        printf("CreateProcess failed (%d).\n", GetLastError());
        return;
    }

    // Wait until child process exits.
    WaitForSingleObject(pi.hProcess, INFINITE);
    // Close process and thread handles. 
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
       

    cout << "we are done!\n";
}

thanks for your help in advance


Solution

  • Are you compiling in Unicode or Multibyte (MBCS)?

    Assuming you are compiling in Unicode you can avoid the use of string objects and use wstring objects instead.

    To initialize a wstring you have to prefix the double quoted string with an L, i.e.

    wstring first(L"C:\\Users\\User\\source\\repos\\1\\x64\\Debug\\1.exe");
    

    So, you can avoid the use of temp variable.

    Note: Is more efficient to initialize a (w)string using the constructor instead of the assignment operator.

    Also, the cast in

    string s1 = " 1.exe 1\0";
    LPWSTR cl1 = (LPWSTR)s1.c_str();
    

    is nos valid, as s1.c_str() return type is const char* (or LPCSTR).

    Instead, you can declare

    wstring s1(L" 1.exe 1\0");
    LPCWSTR cl1 = s1.c_str();
    

    In fact, you don't need to assign the result of c_str() to another variable. You can call to c_str() when you are calling to CreateProcess. The code could be something as:

    //Initializing a name of our file
    wstring first(L"C:\\Users\\User\\source\\repos\\1\\x64\\Debug\\1.exe");  
    wstring s1(L" 1.exe 1\0");
    
    // Start the child process. 
    if (!CreateProcess(first.c_str(),   // No module name (use command line)
        const_cast<LPWSTR>(s1.c_str()),        // Command line
        NULL,           // Process handle not inheritable
        NULL,           // Thread handle not inheritable
        FALSE,          // Set handle inheritance to FALSE
        CREATE_NEW_CONSOLE,              // Creating console for our application
        NULL,           // Use parent's environment block
        NULL,           // Use parent's starting directory 
        &si,            // Pointer to STARTUPINFO structure
        &pi)           // Pointer to PROCESS_INFORMATION structure
        )
    {
        printf("CreateProcess failed (%d).\n", GetLastError());
        return;
    }
    

    If you are compiling with MBCS you should change wstring by string and remove the L prefix when initializing strings. The rest of the code could remain the same.