create processes in visual c++ - c++

i am using visual c++ 2010 i want to learn create processes in c++ can anybody help where find tutorial or does here exist book?
thanks

You can use the below snippet to create process. Just replace the bold part below with the path of the executable which needs to be run.
PROCESS_INFORMATION processInfo; //we get this as an [out] parameter
STARTUPINFO startupInfo; //this is an [in] parameter
memset(&startupInfo,0, sizeof(startupInfo));
memset(&processInfo,0, sizeof(processInfo));
startupInfo.cb = sizeof startupInfo ;
if (CreateProcess("**Executable_Path**", NULL, NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo))
{
// If process is created successfully
WaitForSingleObject(processInfo.hProcess,INFINITE);
CloseHandle(processInfo.hThread);
CloseHandle(processInfo.hProcess);
}
else
{
//Cannot create process.
}

Check Win API CrateProcess function:
http://msdn.microsoft.com/en-us/library/ms682425(VS.85).aspx

Please refer MSDN, the best source for Microsoft related technologies.

Related

Win32 C API: Alternative to broken execl*() family of functions?

So, on Windows, it seems execl() is broken in different ways across different versions of windows. I've spent a lot of time narrowing it down and debugging, and it doesn't really make sense, and I can only think there's something wrong with Microsoft's implementation of execl() (actually execlp() for me).
The only Windows version execlp() seems to work correctly on is 7.
On Windows 10, it works fine, until I compile with -mwindows in MinGW.
Then it just makes my program terminate with a zero exit code.
On Windows XP, it interprets spaces in argument parameters as separate arguments, despite the actual number of arguments being clearly specified by the nature of the function's prototype...
So, looks like I'll have to use some Windows native function and wrap it in "#ifdef WIN32"s.
What I really need is execl() (execlp isn't necessary) like behavior on Windows, in that it replaces the current process image with a new one, and keeps network descriptors open like execl() will.
I'm really at a loss as to what good options are, and while CreateProcess seems somewhat able to do some of it, I can't find enough info on what I'm trying to do.
Any help is appreciated. Thanks!
Unfortunately, you will need a completely different code path on windows, because in the win32 subsystem, creating a process is coupled together with loading and running a new image in a single call: CreateProcess().
In a typical posix scenario, you would fork() your new process, set up things like e.g. file descriptors and then exec*() the new binary. To achieve something similar in Windows, you must rely on the possibilities you get from CreateProcess(). For open files (or sockets), win32 uses "handles" and these can be marked inheritable, for example I do the following for a pipe:
HANDLE pin, pout;
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = 0;
sa.bInheritHandle = 1;
if (!CreatePipe(&pin, &pout, &sa, 0))
{
fprintf(stderr, "Error creating pipe: %lu\n", GetLastError());
return;
}
This way, the pipe's handles are inheritable. Then, when calling CreateProcess(), by passing 1 (or TRUE) for bInheritHandles, the new process inherits all handles marked this way. In this example, I do the following:
STARTUPINFO si;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
si.hStdInput = nul;
si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
si.dwFlags |= STARTF_USESTDHANDLES;
// simple example, my production code looks different, e.g. quoting the command:
char cmdline[1024];
strcpy(cmdline, exename);
strcat(cmdline, " ");
snprintf(cmdline + strlen(cmdline), 1024 - strlen(cmdline), "%" PRIxPTR, (uintptr_t)pout);
// [...]
PROCESS_INFORMATION pi;
CreateProcess(0, cmdline, 0, 0, 1, 0, 0, 0, &si, &pi);
In the child, the pipe could be used like that:
uintptr_t testPipeHandleValue;
if (sscanf(argv[1], "%" SCNxPTR, &testPipeHandleValue) != 1)
{
exit(EXIT_FAILURE);
}
int testPipeFd = _open_osfhandle(
(intptr_t)testPipeHandleValue, _O_APPEND | _O_WRONLY);
FILE *testPipe = _fdopen(testPipeFd, "a");
setvbuf(testPipe, 0, _IONBF, 0);
Of course this will look different for a network socket, but I hope the general idea helps.

Using CreateProcess to run a game executable

I'm making a custom UI at the moment so I'm trying to launch a game from within my C++ application using CreateProcess. Here is my code so far
PROCESS_INFORMATION Processinfo;
STARTUPINFO StartupInfo;
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = sizeof(StartupInfo);
ZeroMemory(&Processinfo, sizeof(Processinfo));
if (CreateProcess(TEXT("C:\\Program Files(x86)\\Steam\\steamapps\\common\\Surgeon Simulator VR Meet The Medic\\Win32\\SurgeonVR.exe"),
GetCommandLineA(),
NULL,
NULL,
false,
CREATE_SUSPENDED,
NULL,
NULL,
&StartupInfo,
&Processinfo))
{
system("pause");
}
Im not quite sure where I'm going wrong as I've never used CreateProcess before, but after looking through a ton of examples I tried to mimic what everyone else was doing to no success.The process isnt being created, and the game is not being launched. Any help is greatly appreciated!
Fixed the issue by using char* path = "C:\Program Files(x86)\Steam\steamapps\common\Surgeon Simulator VR Meet The Medic\Win32\SurgeonVR.exe"; and then using path as a parameter instead. I think the issue was a mistake in the path variable as well as using CREATE_SUSPENDED as a parameter.

Starting Speech Recognition with CreateProcess() in C++

I need help with my simple program, which tries to create a new process running Speech recognition.
When I open cmd and type in the command C:\Windows\Speech\Common\sapisvr.exe -SpeechUX then the speech recognition would successfully start. It will start even when running through system(C:\\Windows\\...) which basically just mimics cmd.
However, when creating the new process with CreateProcess() as below, the function fails. If I put whole path and argument into second parameter CreateProcess(NULL, TEXT("C:\\Windows...\\sapisvr.exe -SpeechUX"), ...), then I get a runtime exception: Access violation writing location
#include <windows.h>
int main()
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
if (!CreateProcess(
TEXT("C:\\Windows\\Speech\\Common\\sapisvr.exe"), //Module name
TEXT(" -SpeechUX"), //command line params
NULL, //Process attributes
NULL, //Thread attributes
FALSE, //Handle inheritance
0, //No creation flags
NULL, //Use parent's environment
NULL, //Use parent's starting directory
&si, //Pointer to STARTUPINFO structure
&pi )) //Pointer to PROCESS_INFORMATION structure
{
printf("error creating process\n");
return 1;
}
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
}
First I tried to test CreateProcess function with running notepad with an argument to open an existing file. When I put path to notepad.exe to first parameter and name of the file to the command line parameter, it didn't recognise it and opened a new file instead.
This whole applies as well to trying to run msconfig.exe from my program, which doesn't take any parameters, so I guess the problem is somewhere else, I just have no idea where.
I searched the web and none of the answers actually worked for me. I'm working in Visual Studio 2015 on Windows 8.1.
Thanks for help.
The CreateProcess function has a second argument as an LPTSTR. For the CreateProcessW version of this function, this must be a writeable buffer, not a string literal. Thus your program's behavior is undefined. Since you are getting an access violation writing to a location when calling CreateProcess, we will assume that CreateProcess is being mapped to CreateProcessW.
At the link posted, here is the quote:
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.
So the fix is simply define an array, not a literal:
TCHAR commandParam[] = TEXT(" -SpeechUX");
if (!CreateProcess(TEXT("C:\\Windows\\Speech\\Common\\sapisvr.exe"),
commandParam,
...
}
or if passing NULL as the first argument:
TCHAR commandParam[] = TEXT("C:\\Windows\\Speech\\Common\\sapisvr.exe");
//...
if (!CreateProcess(NULL, commandParam, ...
Also, if CreateProcess returns an error, you should call GetLastError and optionally FormatMessage, to get the error that occurred, and not simply output that there is an error.

How do i program my current program to input a command into another console in C++?

After creating a process (addaccount.exe) using my current process (run.exe), how do i program run.exe to input a command or pass information directly to addaccount.exe?
Edit:
So, if i have
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.hStdInput = //What do i put here?
If you're using CreateProcess WIN32 function to create the new process, then you can set the standard input and output file handles of the new process. See the STARTUPINFO structure, especially the three file handles at the end of that structure.
You can find a complete example here:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx

Using a handle to collect output from CreateProcess()

I am using CreateProcess() to run an external console application in Windows from my GUI application. I would like to somehow gather the output to know whether there were errors. Now I know I have to do something with hStdOutput, but I fail to understand what. I am new to c++ and an inexperienced programmer and I actually don't know what to do with a handle or how to light a pipe.
How do I get the output to some kind of variable (or file)?
This is what I have a the moment:
void email::run(string path,string cmd){
WCHAR * ppath=new(nothrow) WCHAR[path.length()*2];
memset(ppath,' ',path.length()*2);
WCHAR * pcmd= new(nothrow) WCHAR[cmd.length()*2];
memset(pcmd,' ',cmd.length()*2);
string tempstr;
ToWCHAR(path,ppath); //creates WCHAR from my std::string
ToWCHAR(cmd,pcmd);
STARTUPINFO info={sizeof(info)};
info.dwFlags = STARTF_USESHOWWINDOW; //hide process
PROCESS_INFORMATION processInfo;
if (CreateProcess(ppath,pcmd, NULL, NULL, FALSE, 0, NULL, NULL, &info, &processInfo))
{
::WaitForSingleObject(processInfo.hProcess, INFINITE);
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
}
delete[](ppath);
delete[](pcmd);
}
This code probably makes any decent programmer scream, but (I shouldn't even say it:) It works ;-)
The Question: How do I use hStdOutput to read the output to a file (for instance)?
Microsoft has an example in its knowledge base that demonstrates how to capture the output of a child console process. The basic principle is that the parent process creates pipes (one per standard handle to redirect) and passes the handles to CreateProcess.
The child process does not need to be modified for this to work, which is important if you do not have control over the child's source.
More information: How to spawn console processes with redirected standard handles