I am using CreateProcess function for creating the process, is there any option to get the current state of the process (running or not). Kindly guide me how can I make it possible.
Use OpenProcess function with that dwProcessId if it returns NULL Process is not running otherwise it will return handle to that process
Create process returns a handle to the process in PROCESS_INFORMATION structure, you can use this with something like GetExitCodeProcess to work out if it is still running, or you can use the wait functions to wait for it to exit.
Related
I use CreateProcess to start a .exe of mine. I want to know if everything worked fine or if it encouter errors when I tried to start this .exe.
From what I can tell, I need to use GetLastError(), but I tried to simulate an error in the process path but it return the same last error code.
So I want to catch if CreateProcess is successfull or not and if the process is done. What should I do to achieve that ?
Thanks.
All the information you are looking for is spelled out in the documentation for CreateProcess:
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.
Note that the function returns before the process has finished initialization. If a required DLL cannot be located or fails to initialize, the process is terminated. To get the termination status of a process, call GetExitCodeProcess.
If you need to wait for the target process to terminate, call WaitForSingleObject on the process handle returned in the PROCESS_INFORMATION filled out by the call to CreateProcess.
Since you control the target process, you are free to choose any scheme that allows you to determine success or failure from the process' exit code. You can call GetExitCodeProcess at any time after the process' handle transitioned to the signaled state, and before you call CloseHandle on it.
There are several approaches I can think of:
#1 - Enumeration
You can enumarate the processes and check if the PID is in the list. Check out EnumProcesses
#2 - Checking Exit Codes
You can use GetExitCodeProcess. It will return STILL_ACTIVE (259) if the process is still running
#3 - Process Handles
WaitForSingleObject uses a Process handle with the SYNCHRONIZE access right and returns 0 if the process is not running.
Note: You should not specify INFINITE for the dwMilliseconds parameter because the function would not return until the process state became signaled(process is terminated).
Can someone please explain to me what is the differance between:
OpenProcess and CreatProcess.
(I am trying to inject a DLL into a program and I dont know which one to use.)
OpenProcess is passed a process ID for an existing process, and returns a process handle for that process.
CreateProcess creates a brand new process, returning a handle to that new process (amongst other things).
If you want to inject into a process that is already running, then you will need OpenProcess.
In relation to injecting a .dll into another process,there are a couple of major benefits and differences between OpenProcess and CreateProcess.
The first is timing. You can inject the dll before the target process has had a chance to perform any of their own code by creating the process in a suspended state (dwCreationFlags with CREATE_SUSPENDED(0x00000004) set). Don't forget to resume the process once you are ready for it to execute.
The second is privilege. The process handle returned by CreateProcess automatically has PROCESS_ALL_ACCESS without the need to set SeDebugPrivilege first. OpenProcess does require your program to gain this privilege before it is allowed to use the PROCESS_ALL_ACCESS flag.
Some other minor things to remember:
CreateProcess cannot be called on a running process, but you can always call OpenProcess after CreateProcess if you needed to for whatever reason.
CreateProcess requires you to CloseHandle both the process and thread handles returned in PROCESS_INFORMATION, where OpenProcess only requires you to CloseHandle on it's return value (No thread handle gets opened).
If you need to change the Environment for whatever reason(unlikely), you'll have to use CreateProcess.
Further reading can be found:
CreateProcess
OpenProcess
process-security-and-access-rights
I need to know how to get a handle of a newly created process in C/C++ code. I don't know much about all those Microsoft libraries and I've just read about 2 ways to create a process. First is via ShellExcecute call and the second via CreateProcess but none of these retern a HANDLE. I need to know a handle of the process because I want the main thread to wait for process to finish before it continues. Best of all I'd like if someone help me write a function which looks like this:
HANDLE create_process(/*parameters same as for ShellExecute*/)
{
...
}
Please help.
CreateProcess() returns a PROCESS_INFORMATION structure which contains the process handle. See here and here.
Whilst ShellExecute() does not give you the information that you need, ShellExecuteEx() returns the process handle in the SHELLEXECUTEINFO structure. See here and here.
I would suggest that you look at the MSDN documentation for the API functions that you're using as it's very useful.
CreateProcess returns the handle to the process in PROCESS_INFORMATION.
I need to get the PROCESS_INFORMATION of an external process for use in my application, I have the process handle and process ID, but I don't know how to go about getting the PROCESS_INFORMATION out of that.
I'm using C++(11), Visual Studio 2012, running on Windows. Any help would be greatly appreciated.
PROCESS_INFORMATION is filled by CreateProcess(). That ship has sailed; the process was already started.
Let's focus on what you really want to do. To find out if a process has terminated, first use OpenProcess() to obtain a handle to the process. You'll need the PID, which you already have. Then WaitForSingleObject() will tell you if it is terminated. Pass INFINITE for the 2nd argument to block until the process terminates. Pass 0 if you want to poll. Finally, use CloseHandle() to clean up.
PROCESS_INFORMMATION provides 4 pieces of information:
HANDLE hProcess
HANDLE hThread
DWORD dwProcessID
DWORD dwThreadID
You say you already have two of those values - the Process Handle and Process ID. So that just leaves the Thread Handle and Thread ID. Those belong to the first thread created for the process. You can use CreateToolhelp32Snapshot(), Thread32First(), and Thread32Next() to enumerate the running threads looking for Thread IDs that belong to a given Process ID, and then use OpenThread() to get the Thread Handle of a given Thread ID. The tricky part is identifying which Thread ID is the first thread. That information is not readily available outside of CreateProcess().
The information you need can be obtained with the CreateToolhelp32Snapshot function since it returns both the process ID and the parent process ID. An example of its use can be found here.
I'm using the ShellExecuteEx function in a C++ program to launch an Uninstall.lnk file. In my program, I'd like to wait for the uninstaller to finish. My first attempt was to set the SEE_MASK_NOCLOSEPROCESS flag in the SHELLEXECUTEINFO structure and then call WaitForSingleObject on the hProcess handle available in the SHELLEXECUTEINFO structure passed to ShellExecuteEx, but that still seemed to return way too early.
My current suspicion is that this is because the process launched by ShellExecuteEx (does it launch a new shell?) creates new child processes, but doesn't wait for them. So I'm trying to create a "wait for my child process and all the children it launches" function. To do so, I'm trying to use job objects.
I created a job object using CreateJobObject, assigned the process handle returned by ShellExecuteEx to the job and then attempted to wait for the job object. Unfortunately assigning the process to the job failed, and I think this is due to insufficient access rights.
Does anybody know how to set the PROCESS_SET_QUOTA and PROCESS_TERMINATE access rights (which are required for AssignProcessToJobObject to succeed, according to the MSDN) on a process handle, or another way to wait for the process launched by ShellExecuteEx to finish?
UPDATE: I should point out that I'm also launching other applications, not just Uninstall.lnk. One of them is e.g. a ClickOnce application, which is effectively a simple XML file with the file extension .application.
Vista uses job objects for launching links. Therefor the process you try to assign to another job object might already be assigned.
See: this question
Why not to execute target file instead of openning Uninstall.lnk? You could use IShellLink to get shortcut target. Then you'll be able to execute target file via ShellExecuteEx using SEE_MASK_NOCLOSEPROCESS flag.