Closing process start from windows application on application close or exit - c#

I am working on windows application. i have to run some window exe from my app, i am able to do the same but when i close my application these exe remains on running condition, i am not getting how can i close those exe. Please suggest some tips.
To run the Process
private void StartChildProcess(string fileName)
{
Process newProcess = new Process();
newProcess.StartInfo = new ProcessStartInfo(fileName); ;
newProcess.Start();
localProcess.Push(newProcess);
}
To close the process
private void CloseStartedProcesses()
{
while (localProcess.Count > 0)
{
Process process = localProcess.Pop();
if (process != null && !process.HasExited)
{
process.CloseMainWindow();
process.Close();
}
}
}

Some options:
Setup some communication system so the Main application can alert the other application to shutdown (read up on some WCF information or remoting)
Create a do.shutdown file and let the second application check if that file exists, simple but efficient.
Use the process.Kill options
Use Sendkey or equivalent to send a 'quit' key combination

Use Windows API - P/Invoke. FindWindow() or EnumWindows() to get the window handle. Then you can send WM_CLOSE or WM_QUIT to end the application via the SendMessage() function.
Note that if the application checks for user input on exiting (like a MessageBox asking weather the user really wants to quit) the only option might be to send WM_DESTROY which would be equivalent to Process.Kill (at least in respects to causing data loss - I am not certain it is the absolute equivalent).

Try this:
Process[] p = Process.GetProcessesByName("osk");
foreach (var item in p)
{
item.Kill();
}

The reason that the EXE you've ran from your application doesn't terminate once you close your application is probably because the 2nd application runs as a DIFFERENT, SEPARATE process.
If you run another process with System.Diagnostics.Process, it will remain in background until terminated manually or until it finishes it's job.

try this Process proc = Process.GetProcessesByName("processname");
proc.Kill();

Related

MMC process immediately closing, can't link to windows forms

The end goal of what I am trying to do is get the MMC (Microsoft Management Console) Computer Management snap-in (compmgmt.msc) process to be embedded into a Windows Form, or a workaround that will treat it like a modal pop-up menu.
Right now, I am just trying to get mmc.exe itself working, before I try to load a snap-in. The first part of the problem is the mmc.exe process almost exits immediately.
Edit: mmc.exe only exits immediately if the application is built as 32-bit (my machine is 64-bit). If the application is built to be 64-bit, the first process stays, which is what the expected behavior is.
However, I am still curious for an explanation as to why the strange temporary process behavior occurs. Note that the temporary mmc.exe process that is launched is 32-bit, but the final mmc.exe launched is 64-bit. Strange.
The following code will successfully embed iexplore.exe inside a Windows Form, but it fails to embed mmc.exe.
The reason it fails is an exception that occurs at the call to p.WaitForInputIdle();
An unhandled exception of type 'System.InvalidOperationException'
occurred in System.dll
Additional information: Cannot process request because the process has
exited.
As you can see from the error message, the process exits within milliseconds, but from a user's point of view, the MMC's GUI does still pop up as a separate, unrelated process to the original one I started.
This means that another mmc.exe process is being created which seems to have no connection to the original process created.
So the question is: Why is the MMC process immediately closing, with another MMC process opening almost immediately?
Relevant Windows Form code, similar to this question.
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
private void Form1_KeyPress(object sender, EventArgs e)
{
/// Uncomment *one* of these:
//Process p = Process.Start("mmc.exe");
//Process p = Process.Start("iexplore.exe");
Thread.Sleep(500);
p.WaitForInputIdle();
Console.WriteLine("MainWindowHandle: " + p.MainWindowHandle);
Console.WriteLine("Handle: " + p.Handle);
Thread.Sleep(5000);
SetParent(p.MainWindowHandle, this.Handle);
}
Related, but question seems to be more about the Console GUI itself closing, not allowing for editing, as opposed to some underlying process closing.
https://superuser.com/questions/194252/mmc-exe-starts-and-then-immediately-stops
A subsequent issue to this was that even when I located the new mmc process that pops up, it appears to have MainWindowHandle set to null, possibly meaning Windows doesn't recognize it as having a GUI.
The workaround to this was as simple adding sleep (a pause) between creating the "temporary" mmc process, and waiting for the new process to actually be ready. Note that process.WaitForInputIdle(); did not serve as a long-enough wait.
For anyone that might be having the same trouble as I had:
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = Environment.SystemDirectory + "\\" + "mmc.exe";
startInfo.Arguments = "\"" + Environment.SystemDirectory + "\\compmgmt.msc\" /s";
Process tempProcess = Process.Start(startInfo);
tempProcess.WaitForExit();
Thread.Sleep(500); // Added pause!
// Better alternative is to use a while loop on (MainWindowHandle == null)
// with some sort of timeout
Process[] processes = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(startInfo.FileName));
foreach (Process process in processes)
{
// do what you want with the process
Console.WriteLine("MainWindowHandle: " + process.MainWindowHandle);
// Set Computer Management window on top
SetWindowPos(process.MainWindowHandle, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS);
SetParent(process.MainWindowHandle, this.Handle);
SetWindowLong(process.MainWindowHandle, GWL_STYLE, WS_VISIBLE);
process.WaitForExit();
}
But the main issue is figuring out why the first MMC process exits.
It exits because it may need to use a different bit-depth of MMC to run the snapin. As I am just learning now, snapins can be 32-bit or 64-bit. Windows may need to restart the snapin using either C:\Windows\SysWOW64\mmc.exe (1.34 MB (1,409,024 bytes)) or using C:\Windows\System32\mmc.exe (1.71 MB (1,802,240 bytes)).
https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms692753(v=vs.85)
So, for me, the task at hand seems to be how to discover, before launching a snapin, that snapin's bit-depth.

how can I check and kill another instance of my application?

I face to a problem that my customer is already running the application appA. Then they go to desktop (not kill the appA), and upgrade the application with the version up by run appA.ps1 with PowerShell. After that, click on appA after installed -> get an exception. I guess the root cause is that have another instance is running.
My question is how can I check my application is already running? Can I kill it?
Additional, my application is windows 8 store, c#.
If you wand to keep your current instance running and kill all other instances of your application, you can do this:
using namespace System.Diagnostics;
...
// get current process
Process current = Process.GetCurrentProcess();
// get all the processes with currnent process name
Process[] processes = Process.GetProcessesByName(current.ProcessName);
foreach (Process process in processes)
{
//Ignore the current process
if (process.Id != current.Id)
{
process.Kill();
}
}
From Social MSDN:
All the Metro-style applications work in the highly sandboxed environment and there is no way to directly start an external application.
You cannot access windows app processes. Unfortunately, you aren't able to check for running windows apps.
I didn't find another way so far.
No Metro-style application
At first, you need the processes:
var processes = Process.GetProcessesByName("your application name")
To check whether your program is already running:
var isRunning = processes.Length > 1;
Then you loop through them and close the processes:
foreach (var process in processes)
{
process.CloseMainWindow();
// OR more aggressive:
process.Kill();
}

Gaining control over process started by an URI in C#

I'm making a program which opens a configured application after with the passed paramters through an url with shell execute. I achieved this with the following:
ProcessStartInfo procinfo = new ProcessStartInfo(URI);
procinfo.UseShellExecute = true;
Process App = Process.Start(procinfo);
I want to kill this process later after some minutes through this project that I could do by App.Kill() but the problem is that the Process.Start() always returns null if I pass the URI. How could I reach that process?
If the address of the executable file to start is a URL, the process
is not started and null is returned.
http://msdn.microsoft.com/en-us/library/53ezey2s.aspx
Even if you specify a browser, the process could be a simple handler that sends a message to an existing process (or opens another process) and closes itself immediately.
But you may explicitly launch the browser you want if you know how its process works.
Process p = Process.Start(browserExePath, url);

C# Service calls Console Application that doesn't close

What I have is a windows Service calling a console application that i'm running. However, when the service run it again, the console app doesn't close. is it best to have the app close itself when it's done running or have the service close it? In either cause can you give an example on how to close it?
while (true)
{
try
{
string ectory = #"C:\Program Files\Checker.exe";
EventLog.WriteEntry("PriceGrab", "Calling executeable");
var p = Process.Start(ectory);
if (!p.WaitForExit(30000))
{
p.Kill();
}
System.Threading.Thread.Sleep(600000); // wait 10 minutes
}
catch (Exception ex)
{
EventLog.WriteEntry("PriceGrabCall", ex.Message, EventLogEntryType.Warning);
}
This is what I have inside of my Service executable. This will not close the app. The app is designed to run once every 10 minutes. N/M works now...
It depends on the nature of the console app. If it's like a server app and it won't quit (has an infinite loop...), then you just start it once and only kill it when you don't need it anymore (or just leave it running...). If it's supposed to exit, you can give it some time to close itself, and then kill it if it didn't finish:
var p = Process.Start( ... );
// ...
if (!p.WaitForExit(5000)) { // wait 5 seconds
p.Kill();
}
But be careful when killing processes like this. You might lose the work that they were doing.
Just a suggestion that may be more robust: I've done something similar in the past and have used a solution where the console app is scheduled via Windows Task Scheduler every 5 mins or so and the service checks for new files created by the console app using a file system watcher.

how to block a user from opening new process like internet explorer or firefox?

I am looking for a way to block a user from opening new IE or firefox windows. Is there a way to do this using c#. I am looking at system.diagnostics
You could use a windows service since it runs on background and use this code to terminate a process (the code terminates a detected running internet explorer process)
while (true)
{
StartLoop:
try
{
foreach (System.Diagnostics.Process process in System.Diagnostics.Process.GetProcesses())
{
if (process.ProcessName.ToUpperInvariant().Equals("IEXPLORE"))
process.Kill();
}
}
catch
{
goto StartLoop;
}
}
How about making a group policy for the "testing account" that excludes most of the start menu and the desktop. Make your program the only one that can run.
It won't guarantee that another process won't be started, but it will certainly make it more difficult.

Categories