C# Detecting Spawned Processes - c#

I'm writing a piece of c# code that launches an installer and waits for it to return before continuing with other stuff.
I'm having trouble with certain installers that spawn other processes with the original process returning before the install has actual finished. Is there some way that I can wait until all the processes have finished?
To clarify here's the scenario I'm having trouble with:
Launch Installer1
Installer1 spawns/launches another installer (Installer2)
Installer 1 returns
Application thinks install has finished but Installer2 is still running. This causes issues with workflow in the app.
Here's the code I'm using at the moment:
// launch installer
Process process = windowsApplicationLauncher.LaunchApplication(_localFilePath);
// wait for process to return
do
{
if (!process.HasExited)
{
}
}
while (!process.WaitForExit(1000));
if (process.ExitCode == 0)
{
_fileService.MoveFile(_localFilePath, _postInstallFilePath);
_notification.SetComplete(false);
return true;
}
return false;

Have you thought about using WMI to solve this problem?
You can use WMI to listen for process creation and deletion events. Question 967668 has a good example.
When you receive a process creation event, you could issue a WMI query to determine if the process is a child (or a child of a child etc) of your root installer with something like the following:
"SELECT * FROM Win32_Process WHERE ParentProcessId=".

It might be better to do it this way inside the do / while loop:
System.Diagnostics.Process[] procs = System.Diagnostics.Process.GetProcessesByName(proc.ProcessName, Environment.MachineName);
Then iterate through the procs to find out which is still running...by using the HasExited property...
The logic being that the process's subprocesses are owned by your code, so you could check first if they have exited or not, if not, keep looping...
Hope this helps,
Best regards,
Tom.

Related

Kill a specific event handle of a running process?

I am trying to close a specific singleton handle associated with a process. The windows application "Process Explorer" allows you to do this but you need to select the process, then right click on the handle and select close. I am after a solution that will allow me to auto close the specific handle when the application is running.
I know I can get all processes and even kill a process by simply doing:
foreach (var p in Process.GetProcessesByName("your.exe"))
{
p.Kill();
}
But how would I go about closing a handle attached the process and not the process itself?
I ended up using NtDuplicateObject as Michael suggested in the comments. It was a bit of a pain to implement but everything works as expected - thanks Michael!

Determine and kill the process under my application is running

This might sound odd, but I need to find a solution to kill the process my tool is running under from the code.
I can kill all the processes having the name:
foreach (Process process in Process.GetProcessesByName("name_of_my_tool"))
{
process.Kill();
}
But there might be multiple instances of the tool, and I only want to kill the current one.
So can I somehow get the id, and kill the process by it? Basically I need a suicide function.
What's wrong with this simple snippet?
Process.GetCurrentProcess();

How to stop process in C#, knowing its filename?

I have a programm that runs another one (lets call the first app Stater and the second app - Worker).
I use
process.start();
process.waiForExit();
process.Close();
in Starter.
But if Starter is forced to close while waiting for Worker (for some extern reason) Worker will be still in processes, blocking files, eating memory etc.
So, I want to check if Worker is already running before I will try to start it.
I've tried Process.GetProcessesByName("worker.exe") but no luck (even if I can see Worker in Task Manager).
I've seen some topics here about checking every process in memory for its modules, but still I already know the running file I hope to avoid such solution.
Any advices?
The reason you cannot find it is because you're using .exe. If the executable shows up as worker.exe in TaskManager, just call:
Process[] workers = Process.GetProcessesByName("worker")
foreach (Process worker in workers)
{
worker.Kill();
worker.WaitForExit();
worker.Dispose();
}
At the time of starting Worker process, save its ID in your application's configuration/setting file, in this way when you will launch your Starter process, it will first load that ID from settings file and will check if that process is currently running or not. If you want to immediately close Worker process, you can call process.Kill() on it.
This is much easier...
System.Diagnostics.Process.Start("cmd.exe","/c taskkill /IM notepad.exe");
This code will close the Notepad (if it is running). Type the program name you want to close with it's extension (.exe).
Some applications cannot be stopped without forcing.
Use /F after taskkill to force the action.
If you want to close the process tree use /T after program name.
System.Diagnostics.Process.Start("cmd.exe","/c taskkill /F /IM notepad.exe /T");
When you call GetProcessesByName("worker") you don't specify exe extension as explained in MSDN
And if you wish to keep a global variable with the process object that you have started you could simply use the process.Kill();
If you only need to detect that "worker" is running, a technically much superior solution is have it lock a global mutex for the duration of its lifetime. Any process that knows the mutex name (which is under your control) can then see if the mutex is locked (if it is, worker is running).
However this is not easy to implement correctly as there are many little details you want to get just right; even then, there might be a race condition of "starter" and "worker" are actually launched simultaneously etc (of course this problem, and many others, also apply to all other solutions so it cannot be considered a drawback).

Alternative methods to kill a running process in C#

I am having a bit of trouble trying to terminate a process, I realize there is a fair amount of recourses on this site alone, but I was wondering if there's any alternative ways of terminating an application rather than something typical such as:
Process[] procs = Process.GetProcessesByName("test");
foreach (Process proc in procs)
proc.Kill();
There's Process.CloseMainWindow, which nicely asks the process to quit (as opposed to Process.Kill, which shoots down the process and can have negative side effects).
There are only 2 ways in C# to close the Process (AFAIK) using Process.Kill() and Process.CloseMainWindow(), Kill sends an immediate KILL signal to the application and forces it to close immediately. CloseMainWindow uses SendWindowMessage to send a CLOSE signal to the main application. Kill can be unsafe because it immediately stops the process. CloseMainWindow can be followed by Process.WaitForExit so that you can be sure that the application has closed and may continue to do work knowing that the process you told to exit has exited correctly. As posted by Heinzi's comment please be a little more specific I'm just trying to expand on what was said in the hopes that this is what you require.
Very simple, just need to get the process name and kill it, don't try to do anything fancy, sometimes less is more...
Process[] prs = Process.GetProcesses();
foreach (Process pr in prs)
{
if (pr.ProcessName == "test")
{
pr.Kill();
}
}
This idea is not good. There could be another running process(es) with that name. Do you want any process with that name to be terminated? Unless you are writing a Task Manager/Process Explorer kind of application, you should never do that. And even with TM kind of application, you close the process by grabbing its handle/Process object, and not by name.
Thy can't you ask the target process to close itself gracefully? May be you can use a named mutex, the target thread would wait on that mutex. When you signal that named-mutex from another process, the target thread would know it is time to exit and eventually exit.

Retrieve a complete processes list using C#

I am trying to write a C# program to retrieve a complete process list. However I find that an application open a window but I don't see it in the process tab of Windows task manager, I see it in task tab. In addition, I also cannot get its information using my C# code.
static void showProcesses()
{
Process[] procs = Process.GetProcesses();
foreach (Process proc in procs)
{
Console.WriteLine(proc.ProcessName);
}
}
I browsed many forums but I can only find the methods to hide a process, and I don't find any method for showing hidden processes. Do anyone have idea how to retrieve hidden process information?
There are no hidden processes on Windows. Only processes you do not have (security) rights to see.
A process running as an administrator (in Vista/Win7/Win2k8 would need to be elevated) will always be able to see all processes.
However, a console application that lists the processes may well exit before Task Manager's display refreshes, and thus won't be seen. This is likely with a simple program even with update speed set to "high".
You need to keep your process around until Task manager has updated its display. The simplest way would be do add the following statements to the end of your Main method:
Console.Write("Press ENTER to exit");
Console.ReadLine();
I'm not sure what you mean. The code above lists the same number of processes as pslist. When you talk about methods to hide a process are you talking about root kits? If so they usually work by changing how the list commands work. I.e. the processes are in fact being enumerated, but the info is not displayed to the user.
it works just fine all you need is add :
Console.Write("Press ENTER to exit");
Console.ReadLine();
at the end or start project with ctrl + F5

Categories

Resources