I can check if my process is in a job via IsProcessInJob with null. But I need a handle to this job. How do I go about this?
We have an automation system that wraps processes in job objects. However we have to call a script provided to us which is launching a process outside of this job object. So we need to manually add that process so that if the job fails and has to be killed it is also killed.
Windows provides no supported method to open the job object associated with your process; it is the responsibility of the process that creates the job object to provide a way for other processes to find it, if it is desirable that they are able to do so. However, since the only reason you wanted to put the child into the job was so that it could be killed by the automation system, there is an alternative solution.
Instead of trying to put the child into the existing job object, create a new job object, one under your own control, and assign the child to it. Set the JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE basic limit flag so that the child (and any children it may have) will be killed when your job object is deleted, and make sure that your handle to the job object isn't inheritable.
If the automation system kills your process, or if it exits for any other reason, Windows will automatically close the handle and delete the job object, killing the child processes as desired.
Harry Johnstons suggestion worked.
If the only reason to put the child into the job is so that it can be killed, you might be able to do that another way. Put the child into a newly created job object, with JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE set, and make sure the job handle isn't inheritable. If your process is killed, the job handle will be closed, causing the child to be killed.
Related
I am working with Activiti 5 REST API interfaceintegrated with Spring Boot Activiti Starterand I am trying to complete a process instance. I was able to instantiate a process definition, walk through the process instance tasks and complete each of them. It correctly works until the end of the process, when there are no pending tasks left. I would expect the process instance to be completed - i.e. completed: true-, as I have an end event (terminateEventDefinition), but it is not.
I could not find the REST Api to complete the process instance. So, what's the correct way of managing process instance completion?
Thanks.
Perhaps I am missing something, but after the last task is completed the process will end normally and no longer visible in the /runtime/process-instances list.
Now, you mention that you complete the instance with a Terminate End Event, Terminate End events will complete the instance but will not set the "complete" flag. Terminate is typically used for cancelling a running process.
Instead of terminate, you should use a regular end event, this should set the complete flag.
Again, maybe I am missing somethign in your description.
Thanks
Greg
I have a .NET application which spawns multiple child 'worker processes'. I am using the Windows Job Object API and the JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE setting to ensure the child processes always get killed if the parent process is terminated.
However, I have observed a number of orphaned processes still running on the machine after the parent has been closed. Using Process Explorer, I can see they are correctly still assigned to the Job, and that the Job has the correct 'Kill on Job Close' setting configured.
The documentation for JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE states:
"Causes all processes associated with the job to terminate when the last handle to the job is closed."
This would seem to imply that a handle to the Job was still open somewhere... I did a search for handles to my Job object, and found instances of WmiPrvSE.exe in the results. If I kill the relevant WmiPrvSE.exe process, the outstanding handle to Job is apparently closed, and all the orphaned application processes get terminated as expected.
How come WmiPrvSE.exe has a handle to my Job?
You may find this blog in sorting out what WmiPrvSE is doing.
WmiPrvSE is the WMI Provider host. That means it hosts WMI providers, which are DLLs. So it's almost surely the case that WmiPrvSE doesn't have a handle to your job, but one of the providers it hosts does. In order to figure out which provider is the culprit, one way is to follow the process here and then see which of the separate processes holds the handle.
Once you have determined which provider is holding the handle you can either try to deduce, based on what system components the provider manages, what kind of query would have a handle to your Job. Or you can just disable the provider, if you don't care about losing access to the management of the components the provider provides.
If you can determine what kind of query would be holding a handle, you may be able to deduce what program is issuing the query. Or maybe the eventlog can tell you that (first link above).
To get more help please provide additional details in the OP, such as which providers are running in WmiPrvSE, any relevant eventlog events, and any other diagnostics info you obtain.
EDIT 1/27/16
An approach to find out what happened that caused WMIPrvSE to obtain your job's handle is to use Windbg's !htrace extension. You need to run !htrace -enable after you load you .EXE but before you execute it in Windbg. Then you can break in later and execute !htrace <handle> to see stack traces when the handle was manipulated. You may want to start with this article on handle implementation.
I am trying to attach debugger(windbg,ollydbg) to running process but there's an error saying Debugger is already attached then how can i detach that unknown debugger from that process?
Process includes multi thread, one thread can be attached to debugger and other can't.
The process might be spawning a second process which attaches to the first process for debugging using DebugActiveProcess() in order to prevent people from debugging the first process. Keep in mind that a process cannot debug itself using this method, so a second process must be spawned to do this.
Things you could try:
Use any sort of process monitor or even task manager to figure out what process the first process spawns
Inject code into the second process to call DebugActiveProcessStop() to detach it from the first process
Hook DebugActiveProcess() (kernel32.DebugActiveProcess, ntdll.ZwDebugActiveProcess, or in kernelmode) and redirect it to attach to a different dummy process
Kill the second process
Prevent the second process from getting a handle to the first process with the needed permissions - DebugActiveProcess() will then fail
Use alternative debugging methods (Cheat engine with VEH debugging for example) that don't use the normal debugging API's and therefore bypass this problem
I wanted to know if there was any way of checking if a particular process was started by the user by him/her double clicking, typing the required commands in cmd, via the address bar in explorer, etc. or by another program using CreateProcess() or ShellExecute().
I tried checking the parent process id of the created process but failed to see any consistency among the parent pids of the user initiated processes. I wanted to know if there was any other way or a fool proof way using the ppids.
First you have to determine what the "process started by user" means to you. From Windows' point of view all the processes are started by another processes, whether it was somehow triggered by user or not.
I can only think of getting processes belonging to currently logged on user otherwise i doubt that you can distinguish processes created on a system.
I have a Windows application of which I need multiple instances running, with different command line parameters. The application is quite unstable and tends to crash every 48 hours or so.
Since manual checking for failure and restarting in case of one isn't what I love to do I want to write a "manager program" for this. It would launch the program (all its instances) and then watch them. In case a process crashes it would be restarted.
In Linux I could achieve this with fork()s and pids, but this obviously is not available in Windows. So, should I try to implement a CreateProcess version or is there a better way?
When you call CreateProcess, you are returned a handle to the new process in the hProcess member of the process information struct that you pass to CreateProcess. You can use this handle to detect when the process terminates.
For instance, you can create another thread and call WaitForSingleObject(hProcess) and block until the process terminates. Then you can decide whether or not to restart it.
Or your could call GetExitCodeProcess(hProcess, &exitcode) and test exitcode. If it has the value STILL_ACTIVE then your process has not terminated. This approach based on GetExitCodeProcess necessitates polling.
If it can be run as a daemon, the simplest way to ensure it keep running is Non-Sucking Service Manager.
It will allow to run as win32 service applications not designed as services. It will monitor and restart if necessary. And the source code is included, if any customization is needed.
All you need to do is define each of your instances as a service, with the required parameters, at it will do the rest.
If you have some kind of security police limitation and can't use third party tools, then coding will be necessary. The answer from David Heffernan gives you the appropiate direction.
Or it can be done in batch, vbs or js without need of anything out of the system. WMI Win32_Process class should allow you to handle it.