Create process from service - c++

I'm calling GhostScript(GS) command line tool from C++ code with WinAPI CreateProcess function. When I'm running my application as 'common' executable file, everything works fine, but when I'm running my app as service, something goes wrong - GS process creates and it's listed in task manager processes list but then nothing happens. If I run my application as a service on Windows 7 it works correctly, but on Windows 10 the above problem occurs. Code listed below. I will be grateful for any advice.
std::string cmd = ("gswin32c.exe -sDEVICE=mswinpr2 -dBATCH -dNOPAUSE -dNOSAFER -dNoCancel=true -sOutputFile=\"%printer%HPLJ2000\" \"1.pdf\"");
SECURITY_ATTRIBUTES sa;`sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
auto dwFlags = FILE_ATTRIBUTE_NORMAL;
STARTUPINFOW si;
GetStartupInfoW(&si);
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
ZeroMemory(&pi, sizeof(pi));
if (!CreateProcess(NULL, cmd.c_str(), NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
std::err << "Something went wrong" << std::endl;
}
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);

Your process is probably running on the wrong desktop.
There's a bunch of stuff you need to do to fix this. Full example code here:
https://stackoverflow.com/a/50743993/5743288

Related

How to tell if a process started with CreateProcess is still running?

If I've got a process created through CreateProcess(), how would I determine if it's still running? I know I need to use pi.hProcess but I don't know how, and google isn't really giving me meaningful hints.
PROCESS_INFORMATION pi;
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
bool got_it=CreateProcess(NULL, CA2T(launchString.c_str()), NULL, NULL, false, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
You can use any of the standard wait functions, like WaitForSingleObject(), eg:
switch (WaitForSingleObject(pi.hProcess, 0))
{
case WAIT_OBJECT_0:
// process has terminated...
break;
case WAIT_TIMEOUT:
// process is still running...
break;
}
You can retrieve the process's exit code with GetExitCodeProcess(), which will give the special STILL_ACTIVE value if the process is still running:
DWORD exit_code;
GetExitCodeProcess(pi.hProcess, &exit_code);
if (exit_code == STILL_ACTIVE) {
}

CreateProcess returns true but does not execute with regedit

I am trying to dump a portion of the windows registry in a .txt file using the CreateProcess function. The code is along the lines of
PROCESS_INFORMATION pi;
STARTUPINFO si;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
CString cmdLine = "\"C:\\WINDOWS\\regedit.exe\" /e \"c:\\dump\\TestReg.txt\"
\"HKEY_LOCAL_MACHINE\\SOFTWARE\\MYSOFT\\\"";
LPSTR pCmdLine = (LPSTR)(const char*)cmdLine;
BOOL oc = CreateProcess(NULL, pCmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
if(oc == TRUE)
{
WaitForSingleObject(pi.hProcess, 1000);
GetExitCodeProcess(pi.hProcess, &exitCode);
if(exitCode != 0) ret = -1;
}
What I know
The CreateProcess returns TRUE and the last blocks executes
The process waits for the end and exits normally
However no file is produced at the end
The command line string works fine in command line, even when it operates from the same directory where the program is operating.
I have found something that is potentially useful where someone had basically the same problem. In the end it resulted in a dependency clash but the link does not explain very well how it was detected or fixed.

Failing to open a chrome browser via CreateProcess API

I am trying to open a chrome browser via CreateProcess API. I was not able to do so.
I tried to do like this:
string commandLine = "\"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe\"";
commandLine += " -- ";
commandLine += pURLinfo->szURL;
CreateProcess(commandLine.c_str(), NULL, NULL, NULL, FALSE,
CREATE_NEW_CONSOLE, NULL, NULL, &startupInfo, &processInformation);
CreateProcess returned error 123.
Perhaps there is another way to open it. (i wasn't talking about ShellExecute).
Update: My code now looks like this and still i cannot run chrome.
STARTUPINFOA si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
// Start the child process.
if (!CreateProcessA("C:\\Program Files(x86)\\Google\\Chrome\\Application\\chrome.exe", // No module name (use command line)
NULL,
NULL, // Process handle not inheritable
NULL, // Thread handle not inhberitable
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());
getchar();
return 0;
}
Try to remove unneeded quotes from command line
string commandLine = "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe";

mingw-w64 How to stop console from showing up when opening an external application

I'm trying to write an application to open another and self close, so I don't need the console when the external application opens
This is what I've tried so far:
system("cmd.exe /c application.exe"); //console shows, application opens, console wait
system("start \"\" application.exe"); //console shows, application opens, console close
//console does not show but neither the application (I can see it in task manager)
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
ZeroMemory(&pi, sizeof(pi));
CreateProcess(0, "application.exe", 0, 0, FALSE, 0, 0, 0, &si, &pi);
//console does not show but neither the application (I can see it in task manager)
WinExec("application.exe", SW_HIDE);
This is the way I compile:
g++ -o "launcher" "launcher.cpp" -mwindows
This is some code that works for me to accomplish your goal:
// Declare and initialize process blocks
PROCESS_INFORMATION processInformation;
STARTUPINFO startupInfo;
memset(&processInformation, 0, sizeof(processInformation));
memset(&startupInfo, 0, sizeof(startupInfo));
startupInfo.cb = sizeof(startupInfo);
// Call the executable program
TCHAR cmd[] = myCommandText;
int result = ::CreateProcess(NULL, cmd, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS|CREATE_NO_WINDOW, NULL, NULL, &startupInfo, &processInformation);
In this context, myCommandText is a console command

Creating independent process!

I am trying to create a process from a service in C++. This new process is creating as a child process. I want to create an independent process and not a child process...
I am using CreateProcess function for the same. Since the new process i create is a child process when i try to kill process tree at the service level it is killing the child process too... I dont want this to happen. I want the new process created to run independent of the service.
Please advice on the same..
Thanks..
Code
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si); // Start the child process.
ZeroMemory( &pi, sizeof(pi) );
si.dwFlags = STARTF_USESHOWWINDOW;
if(bRunOnWinLogonDesktop)
{
if(csDesktopName.empty())
si.lpDesktop = _T("winsta0\\default");
else
_tcscpy(si.lpDesktop, csDesktopName.c_str());
}
if(bHide)
si.wShowWindow = SW_HIDE; /* maybe even SW_HIDE */
else
si.wShowWindow = SW_SHOW; /* maybe even SW_HIDE */
TCHAR szCmdLine[512];
_tcscpy(szCmdLine, csCmdLine.c_str());
if( !CreateProcess( NULL,
szCmdLine,
NULL,
NULL,
FALSE,
CREATE_NEW_PROCESS_GROUP,
NULL,
NULL,
&si,
&pi ) )
After closing thread and process handlers of the child process, it's still a child in the Process Explorer, but ending parent process doesn't cause termination of the child one.
CreateProcess( NULL,
szCmdLine,
NULL,
NULL,
FALSE,
CREATE_NEW_PROCESS_GROUP,
NULL,
NULL,
&si,
&pi );
if(pi.hThread)
CloseHandle(pi.hTread);
if(pi.hProcess)
CloseHandle(pi.hProcess);
I've found this decision in sources of cmd.exe of the ReactOS, in the procedure of executing 'start' command.
Create an intermediate process (use create_new_process_group), which then creates the real process.
Service
-> Intermediate Process
-> Real Process
The Intermediate process should exit as soon as it's launched the real process.