I create a process from c++ code, that run a python script.
STARTUPINFO si = {0};
PROCESS_INFOMATION pi = {0};
LPTSTR cmdArgs = _T("cmd.exe /k python myScript.py");
CreateProcess(NULL, cmdArgs, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
The script run in infinite loop, for example:
while (1):
print("hello")
I want to kill the process but nothing really work.
I t ried TerminateProcess(), taskkill with pid - they report that process terminated but it still running.
How can I kill the process while it runnning?
LPTSTR cmdArgs = _T("cmd.exe /k python myScript.py");
CreateProcess(NULL, cmdArgs, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
this code create cmd.exe process and it create python.exe process. question - for what create intermediate cmd.exe ?! you need direct start python.exe. use "python myScript.py" command line and start python.exe direct (if use unicode W api and empty application name - string must not be readonly (in your code it readonly - so you use A api, otherwice you got exception))
TerminateProcess not work - because you have handle of cmd.exe and you can terminate it. but not python.exe.
taskkill with pid - they report that process terminated but it still
running.
of course - pid belong to cmd.exe and it terminated. but python.exe still runing.
so again - solution very simply - direct exec target process, without cmd.exe
Related
The Command CreateProcess With the command WaitForSingleObject
can to open an image?
If Yes How can I open the image?
I tried to open but i don't know Where to put the path to open
if (CreateProcess(NULL, "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Accessories\Paint.lnk", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
If you just want to open an existing image using defualt app then use ShellExectue API. For example:
ShellExecuteW(NULL, L"open", L"Z:\\cat.PNG", NULL, NULL, SW_SHOW);
You could also open image with mspaint using the same API:
ShellExecuteW(NULL, L"open", L"C:\\Windows\\system32\\mspaint.exe", L"Z:\\cat.PNG", NULL, SW_SHOW);
ShellExecuteEx will let you wait for finishing process.
You can do the same using CreateProcess. As #DavidHeffernan pointed out the second parameter of CreateProcess should point to writable memory else it will raise access violation. To make it clear I will just omit the first parameter. Example:
STARTUPINFOW process_startup_info{ 0 };
process_startup_info.cb = sizeof(process_startup_info); // setup size of strcture in bytes
PROCESS_INFORMATION process_info{ 0 };
wchar_t commandline_args[] = L"\"C:\\Windows\\system32\\mspaint.exe\" Z:\\cat.PNG";
if (CreateProcessW(NULL, commandline_args, NULL, NULL, TRUE, 0, NULL, NULL, &process_startup_info, &process_info))
{
//WaitForSingleObject(process_info.hProcess, INFINITE); // uncomment to wait till process finish
CloseHandle(process_info.hProcess);
CloseHandle(process_info.hThread);
}
I strongly recommend to read this CodeProject article (A newbie's elementary guide to spawning processes).
The CreateProcess function can only start .exe and .bat files. Use ShellExecute[Ex] if you want to launch files the same way the shell/Explorer does.
A process must have a PE EXE file as its main file and if you ask CreateProcess to start something else it is just going to fail. ShellExecute will look up the file extension in the registry to find the correct executable (or COM handler) to execute and this often ends up calling CreateProcess on your behalf with the file you specified as a command line parameter.
Using ShellExecuteEx with the SEE_MASK_NOCLOSEPROCESS flag might might give you a process handle you can wait on but you also have to be prepared for hProcess being NULL. This can happen if the registered application for the file type is already running and DDE or COM was used to open the file in this existing application instance...
I'm currently looking for a method to register a process on Windows task scheduler using c++(writing some code).
I have searched some of possible methods on the internet but I could not find any using c/c++.
Using CreateProcess to register a process on task scheduler might be the one solution and I found an example
char buf[MAX_PATH] = "cmd /c schtasks.exe /create /sc onlogon /tn \"APP\" /tr \"C:\\SOME_PATH" /rl highest";
CreateProcess(NULL, buf, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
However, as there is no explanation I do not wish to use this example.
Can anyone please explain to me what the given example is doing or any other way to register a process on Windows task scheduler?
I have used system() to launch IE in my C++ code on a button click. The IE gets launched but a cmd window gets opened too and it gets hanged. I close the cmd window and then it works smoothly. Why is there an initial hang when i first launch the IE?
The cause is that the system() opens a console and calls the command from there. The console only closes when the Internet Explorer closes.
Either use CreateProcess or you can work-around it with system() as well by using the START command:
system("start \"Internet Explorer\" \"C:\\Program Files\\Internet Explorer\\iexplore.exe\" www.google.com");
This code will launch IE using CreateProcess.
However, you may want to use ShellExecute (ShellExecute(NULL, "open", "www.google.com", NULL, NULL, SW_SHOWDEFAULT);) which will use the users default browser.
const char *pathToExplorer = "C:\\Program Files\\Internet Explorer\\iexplore.exe";
const char *webPage = "www.google.com";
char szCmdLine[1024];
sprintf(szCmdLine, "\"%s\" \"%s\"", pathToExplorer, webPage);
STARTUPINFO si = {0};
PROCESS_INFORMATION lp;
si.cb = sizeof(STARTUPINFO);
::CreateProcess( NULL,
szCmdLine,
NULL,
NULL,
FALSE,
CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS,
NULL,
NULL,
&si,
&lp);
I have two application. I will just call them A and B. I have access to the code of application A.
I want to launch the applicaiton B and open a file in that application from A. I am using
CreateProcess method to acheive it. But the application B is not getting opened completely.
I am not sure whether there are any common dlls or other dependencies between these two applications.
The code that I use to open the applicaiton B form A is:
std::wstring appBPath(L"C:\\B.exe");
std::wstring filePath(L"C:\\file.pdf");
std::wstring cmdLineCommand = L"\"" + appBPath+ L"\" \"" + filePath + L"\"";
STARTUPINFO startupInfo;
PROCESS_INFORMATION processInfo;
// set the size of the structures
SecureZeroMemory( &startupInfo, sizeof(startupInfo) );
startupInfo.cb = sizeof(startupInfo);
SecureZeroMemory( &processInfo, sizeof(processInfo) );
CreateProcess( NULL, // No module name (use command line)
&cmdLineCommand[0], // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
CREATE_NEW_CONSOLE, // New process has a new console
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&startupInfo, // Pointer to STARTUPINFO structure
&processInfo ); // Pointer to PROCESS_INFORMATION structure
The exe file starts to load but it gets stuck during the initialisation. But, the application B doesn't terminate.
It goes to some inconsistent state. This issue is happens only only for application A that's installed from it's installer.
It doesn't occur when I run the release or debug build. For the release and debug build we are using VC10. But for installer
build we use VC12. I am not sure on the compiler optimization that are there in place for the installer build.
The CreateProcess function returns success.
Thread state of the application B from process explorer:
Hi I want to execute a system command for allegro and wait till it completes, since I need to access the files generated by this command. My code is not working. Can someone please help? Is the command not running? It works if I do system(command.c_str()) but does not wait.
string command = "start allegro -expert -nographic -s " + fileName1 + " " + boardFile1;
bool ret;
bool retwait;
STARTUPINFO startupinfo;
GetStartupInfo (&startupinfo);
PROCESS_INFORMATION pro2info;
LPTSTR cmdL = (LPTSTR)command.c_str();
ret = CreateProcess(NULL, cmdL, NULL, NULL, false, CREATE_NEW_CONSOLE, NULL,NULL, &startupinfo, &pro2info);
cout<<"hProcess: "<<pro2info.hProcess<<endl;
cout<<"dwProcessId: "<<pro2info.dwProcessId <<endl;
//Want to wait till the command executes
while (retwait= WaitForSingleObject (pro2info.hProcess, INFINITE)!=WAIT_OBJECT_0)
cout<<"waitprocess:true"<<endl; //The process is finished;
CloseHandle (pro2info.hProcess);
I think you don't need "start" at the beginning of command, even if you are using the flag CREATE_NEW_CONSOLE. "start" works with system (because system works with batch command), but if you are creating a new process you should only specify the path to the image file. By the way, the only way to know what's going on is to check the return of CreateProcess (and eventually GetLastError()).
Also, that's not the best way to use WaitForSingleObject. You should catch WAIT_FAILED and use GetLastError(), otherwise your next post on SO will be: "Why isn't my program waiting?" :-)
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx