How to send a command in a Process with C++? [duplicate] - c++

This question already has answers here:
How do I run a program from another program and pass data to it via stdin in c or c++?
(7 answers)
Closed 1 year ago.
I have two application, first app is create a Process:
if( !CreateProcess( myexe, // No module name (use command line)
NULL, // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi ) // Pointer to PROCESS_INFORMATION structure
)
process name is myexe.exe:
myexe waiting a input,
#include <iostream>
using namespace std;
int main()
{
string value;
while(true){
cin>>value;
}
}
How to send input value on cpp?

You need to create pipe, assing handles to STARTUPINFO structure (si) and write data to pipe after you create process.
Look at this example: https://learn.microsoft.com/en-us/windows/win32/procthread/creating-a-child-process-with-redirected-input-and-output

Related

c++ can't pass an argument with CreateProcess [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 4 months ago.
Improve this question
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
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.

How can I use CreateProcess method to refer to other 'ini' file to start 'exe' program?

I'm currently trying to execute 'ClientProc.exe'. This program uses 'SA_Client.ini' file from a same directory as a reference.
I'm using CreateProcess method to execute the .exe program as belows.
STARTUPINFO si;
PROCESS_INFORMATION pi;
// set the size of the structures
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
LPCSTR lpApplicationName = "C:\\projects\\Client\\ClientProc.exe";
LPSTR cmd = (char*)"./";
if (!CreateProcess(lpApplicationName, // the path
cmd, // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi // Pointer to PROCESS_INFORMATION structure (removed extra parentheses)
))
{
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);
The problem is that I don't know how to make CreateProcess to refer to the 'ini' file even though the file exists in the same directory.
I've checked Microsoft document or other StackOverflow comments but couldn't find anything useful.
Does anyone know how to do it?
Thank you in advance!
--Edit--
I've also tried setting the lpCurrentDirectory parameter where ini file exists.
CreateProcess(lpApplicationName, // the path
NULL, // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
"C:\\projects\\Client", // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi // Pointer to PROCESS_INFORMATION structure (removed extra parentheses)
)
Then, I've got an error 267 which stands for 'ERROR_DIRECTORY'. I'm sure that the file exists in the directory. What am I doing wrong?

why argv in createProcess() is different from normal c++ program

this is my code, and i found the first output is "thisProgram.exe"
and the second output is "a".
why?
i read the doc in msdn, however i don't quite clear why the argv[0] can be "a", is there something different in windows when using createProcess. Could someone please tell me the difference from lpApplicationName and lpCommandline? thanks
int main( int argc, char *argv[] ) {
cout << argv[0] << endl;
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
// Start the child process.
if (!CreateProcess("thisProgram.exe", // No module name (use command line)
"a b c", // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
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 1;
}
// Wait until child process exits.
WaitForSingleObject(pi.hProcess, INFINITE);
// Close process and thread handles.
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
}
CreateProcess passes the second argument (the command line) to the new process as its command line. CreateProcess will not prepend the module name. If you want the application name to appear as argv[0] you must repeat the application name in the command line argument.
The documentation says it like this:
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.
It's generally simplest to pass NULL for the application name, and for the command line pass the application name and the arguments concatenated together.

CreateProcess Exception (kernel32.lib) [duplicate]

This question already has answers here:
CreateProcess() fails with an access violation [duplicate]
(3 answers)
Closed 9 years ago.
I am getting an exception when I run this code:
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
CreateProcess(NULL, L"program.dat", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
// Wait until child process exits.
WaitForSingleObject( pi.hProcess, INFINITE );
// Close process and thread handles.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
I get the exception on WaitForSingleObject.
Thanks :)
As clearly as much that can be stated in the documentation::
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.
Yours L"program.dat" falls under this rule. Copy the string in some WCHAR variable and pass that instead.
I can reproduce the exception using your code. I think the problem is that the second arg to CreateProcess is an in/out one. The doc states:
The system adds a terminating null character to the command-line string to separate the file name from the arguments. This divides the original string into two strings for internal processing.
See CreateProcess function
The second arg must NOT point to read-only memory.
Using the Visual Studio debugger and stepping in assembler code, the trap is indeed caused by the _CreateProcessInternal function in Kernel32 trying to write 0x to the end of L"program.dat", which, as a string constant, is in a "non writable" section.
Use below code:
wchar_t * pCommandLine = L"program.dat";
wchar_t CommandLine[ 64 ];
wcscpy( CommandLine, pCommandLine );
CreateProcess(NULL, CommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
and the exception will vanish.
As for Creating a Child Process with "program.dat" ?!? That's another story.

Launch console app from console apps

I am using this piece of code to launch a process from a GUI app. but, according to the notes of this code it is not possible to launch a process from a console app. actually i want to do that, I want a console app to launch another console process, please do you have any idea how to do that?
// This technique must be used for "console-less" parents such as GUI
// applications or detached applications.
// Using the STARTUPINFO STARTF_USESTDHANDLES flag, requires that
// the CreateProcess fInheritHandles parameter be set TRUE so that
// the file handles specified in the STARTUPINFO structure will be
// inherited by the child.
// setup the child process's handles for stdin, stdout, & stderr.
STARTUPINFO childProcStartupInfo;
memset( &childProcStartupInfo, 0, sizeof(childProcStartupInfo));
childProcStartupInfo.cb = sizeof(childProcStartupInfo);
childProcStartupInfo.hStdInput = hFromParent; // stdin
childProcStartupInfo.hStdOutput = hToParent; // stdout
childProcStartupInfo.hStdError = hToParentDup; // stderr
childProcStartupInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
childProcStartupInfo.wShowWindow = SW_HIDE;
// Now create the child process, inheriting handles
PROCESS_INFORMATION childProcInfo; /* for CreateProcess call */
bOk = CreateProcess(
NULL, // filename
pCmdLine, // full command line for child
NULL, // process security descriptor */
NULL, // thread security descriptor */
TRUE, // inherit handles? Also use if STARTF_USESTDHANDLES */
0, // creation flags */
NULL, // inherited environment address */
NULL, // startup dir; NULL = start in current */
&childProcStartupInfo, // pointer to startup info (input) */
&childProcInfo); // pointer to process info (output) */
did you try shellexecute? I think that works..
You can try:
ShellExecute(), ShellExecuteEx(), CreateProcess(), system(), _wsystem().
There are a few more, but one of these got to work for you!
Personally, I would go with CreateProcess and than wait for the process to quit (found on google this example: http://www.codeproject.com/Tips/333559/CreateProcess-and-wait-for-result). Notice that system()/_wsystem() are the easiest to use, but if you're not careful they can be exploited !!!
Hope it helps! :-)
Try this code:
#include <Windows.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[])
{
char* app_to_launch=new char[80];
strcpy(app_to_launch,"app.exe");
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
// Start the child process.
if( !CreateProcess( NULL, // No module name (use command line)
app_to_launch, // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
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() );
}
// Wait until child process exits.
WaitForSingleObject( pi.hProcess, INFINITE );
// Close process and thread handles.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
return 0;
}