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).
Related
I want to open an different app and to appears like it's an process of the app itself and don't appear as a different one in the task manager processes list.
Something like:
Can Process.Start() do it?
Solved!
Well it seems that always when an app starts a process, the main app it'll be its parent. I didn't knew that :)
Using Process.Start with a ProcessStartInfo and ensuring UseShellExecute is false should probably do it. However, the process being launched may do something that breaks this behavior. It could, for example, just be a stub launcher that starts another process then quits.
Is it possible for a running c# application to start/invoke some new arbitrary process, but only do so after the current running application is terminated?
I guess it's possible to call the new process from Process.Start() via cmd.exe and do something like sleep 3 & c:\mynewapplication.exe - this would giver the 'caller' some three seconds to terminate itself.
However this is a bit hacky, and was wondering if there was a neater way?
Depending on the type of application, you could simply listen to the end of the program. One option you have is the Application.ApplicationExit event.
Another possibility is to start another process, that waits until the first process dies. You could poll Process.GetProcesses for example. This will raise the event, even if the first process crashes. You could also register the Process.Exited event.
It has little to do with C#. It is a question about the Windows OS, and, in particular, in WinAPI.
Generally, the only 'thing' that runs code is threads. When your process in terminated, all its threads die.
Your best approach is probably by starting a process that will wait before starting your new process, as you suggested, however you may, for example, hook on some of the functions called when something happens and start your new process there.
i was wrote some codes, when my apps still run, it will close another (example notepad) even the notepad is reopen it will close again, i've try some, but it will close when my apps startup , when my apps is running, and i open notepad, notepad wont close. here
foreach (Process Proc in Process.GetProcesses())
if (Proc.ProcessName.Equals("notepad"))
Proc.Kill();
Your code kills processes that are running at the time you code executes. Once your code has finished executing it no longer exerts any influence. It won't kill processes that are started after your code has finished executing.
Probably you need to detect when the target process starts, and then kill it. You can do that by polling which is rather inelegant. To avoid polling you need WMI. There are many examples of how to do this. For instance: How to detect a process start & end using c# in windows?
I have a code like this:
ProcessStartInfo psi= new ProcessStartInfo(...);
Process process = Process.Start(psi);
Application.Current.Shutdown();
even so the process have the process information of the application (i have logs) in rare cases on the production computer the process is not opened at all.
As I now Process.Start() is synchronous and if it returns a value there must be a running process.
Another information that I have is that the genuine process is also the shell process.
Does anyone have an idea what is the problem?
Process is IO artifact, so there are always some delays, between you start it and it actually opened.
This delay, naturally, depends on concrete machine, where you run your code.
So, like a solution you can
or sleep main thread untill the p process opened, for some amount of time
or close the main thread, only when from (say) some timer you are able to find required p process in the list of already run OS processes.
The second, I think, is a better solution.
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.