I have written an application in C#. But even after closing the form, the application will be running. That is .exe and .vshost files will be still running. So i have used the following Code to terminate the application. But it is not terminating.
public void Form1_Closing(object sender, FormClosingEventArgs e)
{
Process[] pArry = new Process[500];
pArry = Process.GetProcesses();
foreach (Process p in pArry)
{
string s1 = p.ProcessName;
s1 = s1.ToLower();
if ((s1.Equals("new_prj.vshost")))
{
p.Kill();
}
}
}
My project name is new_prj. And if i write the same code snippet in Button_Click function, it works properly. But not working in form closing function. Has anybody come across the same problem?
Can you use this ?
Application.Exit();
There can be several reasons for this.
If it's a multithreaded application then you might have another thread running preventing the process from terminating.
Please provide some more details.
EDIT
I posted a similar question and and got some input about how to use threads. See this post.
Here is a some usefull code from an answer to the post:
public void Start()
{
workerThread = new Thread(() => DoWork());
doWork = true;
workerThread.IsBackground = true;
workerThread.Start();
}
Notice the IsBackground = true;.
If you really want to quit your application from anywhere you can use Environment.Exit() but I would suggest to solve the problem with your form. If you post more of your code we might be able to find the problem.
You can try Application.Exit too, but as Carsten said, you are trying to treat the symptom rather than the cause.
Have you tried simply using Application.Exit()?
Related
I am Working in Visual Studio 2008 Winforms Application project in Windows 7 (32 bit).I am doing the project in C#.
I have placed some buttons in a tab and added actions for that once it is clicked. While clicking the button am just running a .exe file in its action part.
My problem is that, i opened a window by clicking one button(so the .exe file is running), now while am clicking the button again it is opening same window again irrespective of checking that it is open or not. I want to solve this issue,as when a window is opened it must not open again on another click on same button. How to solve this issue. ?
Please help....
Thanks in advance..
You could check if the process is already running, when re-clicking the button:
private void btnStartExecutable_Click(object sender, EventArgs e)
{
Process[] processName = Process.GetProcessesByName("InsertProcessNameHere");
if (pname.Length == 0)
{
MessageBox.Show("Application isn't running yet.");
//Start application here
Process.Start("InsertProcessNameHere");
}
else
{
MessageBox.Show("Application is already running.");
//Don't start application, since it has been started already
}
}
You can try this:
bool processExited = true;
private void button1_Click(object sender, EventArgs e)
{
if (processExited)
{
Process process = new Process();
process.EnableRaisingEvents = true;
process.Exited += MyProcessExited;
process.StartInfo = new ProcessStartInfo();
process.StartInfo.FileName = "notepad.exe";
process.Start();
processExited = false;
}
else
{
MessageBox.Show("Still running");
}
}
void MyProcessExited(object sender, EventArgs e)
{
processExited = true;
}
The right answer here IMHO is that unless the two application shares a common resource or can talk to each other through some channel, there is no safe and efficient way to achieve what you want. Since the process is external, it could already be running before your calling app starts, or even while it's already running. You won't be able to tell if the process has been started from your app or not.
By the time I'm writing this your question does not yet state if you are in liberty to modify the external app you are calling. If you are however, using a Mutex would be a quick and easy way to solve your problem.
In your external app, whenever you want to make the other app aware of whatever condition you want (be it that the process is running or that a specific window is opened), have a Mutex instance created like this:
var mutex = new Threading.Mutex(true, "mutex unique identifier");
And in your calling app, try to create a Mutex instance with the same identifier:
bool alreadyExists;
var mutex = new Threading.Mutex(false, "mutex unique identifier", out alreadyExists);
Here the alreadyExists variable will tell you whether or not the external process is running or not. This is much safer than trying to identify it via its name, as other processes could have the same or a new version could be of a different name. Of course, the mutex identifier must be as unique as possible (like a Guid), otherwise you may encounter the same problem. ;)
Whenever you feel like the mutex must be released (at external app level), release it:
mutex.ReleaseMutex();
Note that if the process ends the mutex will be automatically released by the OS.
If the external app isn't a .NET based app, you can still create a mutex with Win32 API functions.
Thanks for the support.. I got the answer like this..
1) Creating an event'Exit' for the process in function button click
2) Define a function for the exit event where you set a flag
3) Check the flag is set or not everytime while opening the process in the function button click
Event for Exit: 'P' is the name of process:
p.Exited += new EventHandler(p_Exited);
p_Exited will be the function name where we will set the flag.
Thanks all...
If you know the name of the process that gets started or the path the .exe is run from you can use the Process class to check to see if it is currently running.
http://msdn.microsoft.com/en-us/library/system.diagnostics.process(v=vs.110).aspx
Strange, but perhaps I am handling it the incorrect way - I need to quite simply check if explorer.exe is running, and if so kill it. However, the way I am currently achieving this, explorer.exe simply restarts after I kill it.
Normal taskkill through batch works fine though, does C# do something different?
private void Form1_Load(object sender, EventArgs e)
{
Process[] prcChecker = Process.GetProcessesByName("explorer");
if (prcChecker.Length > 0)
{
MessageBox.Show("Explorer running");
foreach (Process p in prcChecker)
{
p.Kill();
}
}
else
{
MessageBox.Show("Explorer is not running");
}
}
That's because Windows takes care of restarting explorer.exe if it happens to die.
It is possible to delay this behavior (the setup of tortoisegit does this, for example), but it's not recommended - users are going to be pissed.
Although not C# way but you can alternatively try to set the registry key HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoRestartShell to 0 to stop the auto restart.
EDIT:-
Try this in C#:-
RegistryKey ourKey = Registry.LocalMachine;
ourKey = ourKey.OpenSubKey(#"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", true);
ourKey.SetValue("AutoRestartShell", 0);
Try to kill the Process with exit code 1 .
Sorry i dont have any example code because i am not a C# programmer but in my application it worked just fine.
I used the C++ Function:
TerminateProcess
I use AllocConsole() to open a Console in a winform application.
How can I prevent the application from exiting when the Console is closed?
EDIT
The update of completionpercentage from time to time is what I want to show in console
void bkpDBFull_PercentComplete(object sender, PercentCompleteEventArgs e)
{
AllocConsole();
Console.Clear();
Console.WriteLine("Percent completed: {0}%.", e.Percent);
}
I tried the richtextBox as the alternative
s =(e.Percent.ToString());
richTextBox1.Clear();
richTextBox1.AppendText("Percent completed: " +s +"%");
But I can't see the completionpercentage update time to time. It only appears when it is 100% complete.
Any alternative?
I know this is a task that seldom pops up but I had something similar and decided to go with a couple hacks.
http://social.msdn.microsoft.com/Forums/vstudio/en-US/545f1768-8038-4f7a-9177-060913d6872f/disable-close-button-in-console-application-in-c
-Disable the "Close" button on a custom console application.
You're textbox solution should work as well. It sounds a lot like your calling a function from the main thread that is tying up the form which is also on the main thread and is causing you grief when updating your textbox. Consider creating a new thread and either an event handler to update your textbox or use the invoke methodinvoker from the new thread to update the textbox. Link below from an already answered question on how to complete this.
How to update textboxes in main thread from another thread?
public class MainForm : Form {
public MainForm() {
Test t = new Test();
Thread testThread = new Thread((ThreadStart)delegate { t.HelloWorld(this); });
testThread.IsBackground = true;
testThread.Start();
}
public void UpdateTextBox(string text) {
Invoke((MethodInvoker)delegate {
textBox1.AppendText(text + "\r\n");
});
}
}
public class Test {
public void HelloWorld(MainForm form) {
form.UpdateTextBox("Hello World");
}
}
Refer to the answers over here. As mentioned in the answers, there is no way to stop the application from getting closed.
But as a workaround, you can have your own text output solution described in one of the answers.
You can build first the console application that recieves arguments and writes it to the console. Place it, where the main application starts.
From main application you can first kill process and then reopen it with a new argument.
It's the altarnative way.
I ran out of ideas and couldn't find any reference about it so here I go...
I need to keep a secondary application wich is not related to my c# project always running in background. So if this secondary application crashes or someone else close it manually it will automatically re launch again via my c# app.
I have no clue of how to accomplish this one, I mean checking if this application closes by something external to my c# app.
Any help would be greatly appreciated.
Thanks in advance.
The below code is in C# and it is inside a WinForm.
private void Form1_Load(object sender, EventArgs e)
{
Process p = Process.GetProcessesByName("Notepad")[0];
p.EnableRaisingEvents = true;
p.Exited += new EventHandler(p_Exited);
}
void p_Exited(object sender, EventArgs e)
{
MessageBox.Show("Exit");
}
It looks for a Process with Name Notepad & retrieved the first instance of it. It sets EnableRaisingEvents to true on it and hooks to the Exited event. Whenever notepad is closed it would display an alert.
Based on this logic, you can build your app.
As a solution you can use Windows service which invokes your always running application .
You can make that service catch error return codes from the app and restart it depending on errors.
you can keep checking for a process if it is running or not using process class in vb.net
For Each p As Process In Process.GetProcessesByName("communicator")
ShowWindow(p.MainWindowHandle, SHOW_WINDOW.SW_NORMAL)
Next p
if the process you want not inthe list you may launch it again.
Ashish kumar
Simplest way is to run a timer and in the tick event, use-
if (Process.GetProcessesByName("communicator").Count() == 0)
{
Process.Start("communicator.exe");
}
You can use FileSystemWatcher to keep a watch of the file modified by other application.
FileSystemWatcher has events like Changed, Created,Renamed, Deleted, which can be subscribed to keep track of a file changes.
I've been able to use a winforms application to open another winforms application using:
Rhino4.Application oRhino = (Rhino4.Application)Activator.CreateInstance(Type.GetTypeFromProgID("Rhino4.Application"));
But how do I check if it gets closed? Is it possible to create an event that will get fired when the user closes the application?
EDIT
Process[] pr = Process.GetProcessesByName("Rhino4");
for (int i = 0; i < pr.Length; i++)
{
if (pr[i].MainWindowTitle != null)
{
if (pr[i].MainWindowTitle.Length > 4)
{
if (pr[i].MainWindowTitle.Substring(0, 4) == "wall")
{
pr[i].Exited += new EventHandler(caseInfoMenu_Exited);
}
}
}
}
void caseInfoMenu_Exited(object sender, EventArgs e)
{
MessageBox.Show("Window closed");
}
I've managed to identify the process using this code. But the Exited-event doesn't fire when I close the program.
Its maybe not the most elegant solution but indirectly you could do this by checking if the process exist or not and then do this repeatable. This is of course if you do not already have a handle to the process.
void checkProcess()
{
Process[] processes = Process.GetProcessesByName("NameOfProcess");
if (processes.Length == 0)
{
// No such process
}
else
{
foreach (Process proc in processes)
{
// do something with proc
}
}
}
Edit: Some thoughts on this after reading the posts in Abdul's answer plus your own question. This is by no means an answer, but maybe it can help you on your quest.
Firstly, Activator.CreateInstance calls the best fitting constructor on the object type that you give to it and returns a handle to that object. It does create the threads/processes itself and thus it has not knowledge about them. The (9) processes you'll see in your list are probably created by the Rheno4 class itself. There is a discussion about this here.
Secondly, according to msdn the EnableRaisingEvents property should be set to true when the process is created for the Exited event to function correctly. This leaves me wondering what happens when you attach the event after the process is already created?
You could of course iterate over all matching processess before and after calling CreateInstance to extract all new instances of Rheno4 that has been created. But this is far from a bulletproof solution and the risk is that you are fetching processes that are created by someone else or that not all processes are retreived (in case there is a delay in creating the other object). Depending on your needs, however, this maybe is appliable.
Another thought. The processes returned from the GetProcessesByName has a rich set of properties. Maybe you can look though these and find a common denominator for the processes returned. The ones I would start to investigate are: Threads, StartInfo, MainModule.
What about catching Exited event
myProcess.Exited += new EventHandler(myProcess_Exited);
private void myProcess_Exited(object sender, System.EventArgs e)
{
eventHandled = true;
Console.WriteLine("Exit time: {0}\r\n" +
"Exit code: {1}\r\nElapsed time: {2}", myProcess.ExitTime, myProcess.ExitCode, elapsedTime);
}
Source msdn.
If you want to start the application again after closing then :-
I think you need to crearte a Windows Service which will keep checking the process running and if it is closed then start the application again
As far as events are concern then "Closing" and "Close" events are there in Windows App which fires when user shutdowns the app.