CreateProcess command line arguments
Use std::wstring
and string concatenations to build up your command line dynamically, eg:
std::wstring cmdArgslistSetChannel = L"os-util.exe";
cmdArgslistSetChannel += L" 0x273e:0x0007:0x0100";
cmdArgslistSetChannel += L" --set-channel";
cmdArgslistSetChannel += L" 11";
bSuccess = CreateProcessW(
L"os-util.exe",
&cmdArgslistSetChannel[0],
NULL, NULL, TRUE, 0,
NULL, szFileName, &si, &pi);
Alternatively, use std::wostringstream
for the buildup, and then retrieve a std::wstring
from it:
std::wostringstream cmdArgslistSetChannel;
cmdArgslistSetChannel << L"os-util.exe";
cmdArgslistSetChannel << L" " << L"0x273e:0x0007:0x0100";
cmdArgslistSetChannel << L" " << L"--set-channel";
cmdArgslistSetChannel << L" " << L"11";
std::wstring cmd = cmdArgslistSetChannel.str();
bSuccess = CreateProcessW(
L"os-util.exe",
&cmd[0],
NULL, NULL, TRUE, 0,
NULL, szFileName, &si, &pi);
Either way, you can then replace any individual substring as needed.
CreateProcess won't start the proccess with arguments
The second parameter to CreateProcess is the full command line, not just the parameters to the EXE. Lets take two examples :
CreateProcess ("c:\\notepad.exe",
"c:\\notepad.exe c:\\wibble.txt",
...);
will work fine (if there is a copy of notepad.exe and a file called wibble.txt in the root of C:), whereas
CreateProcess ("c:\\notepad.exe",
"c:\\wibble.txt",
...);
will launch the EXE but fail to open the file. What this means is that when the help systems calls the second parameter the command line, it ain't lying - it wants the whole command line.
Note that you can use NULL as the first parameter if the whole command line is in the second param. That's how I normally use it in fact.
C++ Winapi CreateProcess issue with command line
When both lpApplicationName
and lpCommandLine
are used, you need to include the executable path as the first parameter of your lpCommandLine
value, even though you are specifying the executable path in the lpApplication
value. The lpCommandLine
is passed as-is to the spawned process, and most RTLs (especially C-based RTLs, but others as well) expect the first command-line parameter to be the executable path since that is how command-line consoles operate. This is even mentioned in the CreateProcess()
documentation:
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.
This is also covered in MSDN Support:
INFO: Understanding CreateProcess and Command-line Arguments
Behavior of CreateProcess() When Creating a 32-bit Process
Case 1:
If the ApplicationName parameter is passed and the CommandLine parameter is NULL, then the ApplicationName parameter is also used as the CommandLine. This does not mean that you can pass additional command-line parameters in ApplicationName string. For example, the following call will fail with a "File Not Found" error:
CreateProcess( "c:\\MyApp.exe Param1 Param2", NULL, ... )
Case 2:
On the other hand, if the CommandLine parameter is non-NULL and the ApplicationName parameter is NULL, then the API attempts to extract the application name from the CommandLine parameter.
Case 3:
The flexibility of the CreateProcess() function (and a possible point of confusion) arises when you pass a valid string pointer to both the ApplicationName and CommandLine parameters. This allows you to specify the application to be executed as well as the complete command line that is passed to the application. One might assume that the command line passed to the created application is a composite of the ApplicationName and CommandLine parameters, but this is not the case. As a result, a process created by CreateProcess can receive a value other than its .exe name as its "argv[0]" parameter. The following is an example of a call to CreateProcess that produces this "abnormal" behavior:
CreateProcess( "c:\\MyApp.exe", "Param1 Param2 Param3", ...)
MyApp's arguments will be as follow:
argv[0] == "Param1"
argv[1] == "Param2"
argv[2] == "Param3"
NOTE: ANSI specifications require that argv[0] should be equal to the application name, but CreateProcess gives the calling application the flexibility to override this rule for 32-bit processes.
Case #3 applies to your situation.
Use something like this instead:
std::string Command = "<exe path>";
std::string CommandLine = "\"" + Command + "\" <parameters>";
// std::string::c_str() returns a const pointer. The first parameter
// of CreateProcessA() is const, but the second parameter must be a
// non-const pointer to writable memory, because CreateProcessW() can
// modify the data...
//
resultCreate = CreateProcessA(Command.c_str(), &CommandLine[0], ...);
std::wstring Command = L"<exe path>";
std::wstring CommandLine = L"\"" + Command + L"\" <parameters>";
// std::wstring::c_str() returns a const pointer. The first parameter
// of CreateProcessW() is const, but the second parameter must be a
// non-const pointer to writable memory, because CreateProcessW() can
// modify the data...
//
resultCreate = CreateProcessW(Command.c_str(), &CommandLine[0], ...);
Alternatively, omit lpApplicationName
and specify the complete command line to lpCommandLine
only:
std::string CommandLine = "\"<exe path>\" <parameters>";
resultCreate = CreateProcessA(NULL, &CommandLine[0], ...);
std::wstring CommandLine = L"\"<exe path>\" <parameters>";
resultCreate = CreateProcessW(NULL, &CommandLine[0], ...);
CreateProcess and command line arguments
You cannot use command-line redirection operators with CreateProcess()
directly. You have to spawn an instance of cmd.exe and pass the operators to it instead, eg:
CreateProcess( "C:\\windows\\system32\\cmd.exe", t_str2, ...))
Where t_str2
is "/C C:\\Temp\\sift.exe < C:\\img1.pgm > C:\\img1.key"
. The actual path to cmd.exe can be determined by reading the %COMSPEC%
environment variable.
CreateProcessW not honoring commandline
You must to supply the executable in the command
Appname
should contain the full path to the executableCommand
should contain also theargv[0]
if you want to open file t.txt
with notepad than you can give as follows:
Appname = "c:/windows/notepad.exe";
command = "notepad c:/temp/t.txt";
You doesn't even must to supply the real program name, even fake name will do the job, since it is only a place holder.
like this: command = "fake c:/temp/t.txt";
now in notepad.exe:
argv[0] = "notepad";
argv[1] = "c:/temp/t.txt";
See this full example:
#include <Windows.h>
#include <iostream>
using namespace std;
int main(){
STARTUPINFO si = {sizeof(STARTUPINFO), 0};
si.cb = sizeof(si);
PROCESS_INFORMATION pi = {0};
LPTSTR AppName=L"C:/Windows/notepad.exe";
wchar_t Command[] = L"notepad C:/Temp/t.txt";
DWORD res = CreateProcess(AppName, Command, 0, 0, 0, CREATE_DEFAULT_ERROR_MODE, 0, 0, &si, &pi);
if (res) {
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return 0;
} else {
cerr<<"error..."<<GetLastError()<<endl;
};
return 0;
}
CreateProcess doesn't pass command line argument to new process's main function
It seems the OP didn't quite get why the problem occurred. The reason is a misuse of the _T
macro.
Instead of this:
_tprintf( _T ("%d + %d = %d\n", val1, val2, val1+val2));
It should be this:
_tprintf( _T("%d + %d = %d\n"), val1, val2, val1+val2);
The same error appears in all of the other lines in _tmain
that use _T
. The _T
macro takes one argument, and that is a string-literal.
Unable to pass command line to new exe created by CreateProcess
So what you need to do is write to the stdin of that process. I am not familiar with the windows CreateProcess api, so you're gonna have to do some looking yourself. This example on shows several examples with reading a file and stuff into stdin of the called process. There is no easy way to do this kind of thing, so prepare to learn lots about pipes!
Related Topics
Why Is Std::Iterator Deprecated
Is There C/C++ Equivalent of Eval("Function(Arg1, Arg2)")
What the Heque Is Going on with the Memory Overhead of Std::Deque
Catching "Stack Overflow" Exceptions in Recursive C++ Functions
Windows Unicode C++ Stream Output Failure
Write a Recursive Function That Reverses the Input String
Operator Overload Which Permits Capturing with Rvalue But Not Assigning To
I Want to Generate the Nth Term of the Sequence 1,3,8,22,60 ,164 in Order(1) or Order of (Nlogn)
Is There Any Reason to Use C Instead of C++ for Embedded Development
Differencebetween an Empty and a Null Std::Shared_Ptr in C++
Initializing Std::String from Char* Without Copy
Portable Zip Library for C/C++ (Not an Application)
Printf Rounding Behavior for Doubles
What Is the Meaning of Auto When Using C++ Trailing Return Type