Closing the client application using a Singleton class implementation - c#

I have a .net application written in c#. This application is called from a parent application written in c++. When the parent application crashes or accidently closes the .net application still runs. But I want to close the client application too when the parent application crashes or stops.
One of my colleague said we can easily implement this using a singleton class. How can I do that?

You are going to have to poll to see if the parent application is still running.
One way to do this is setting up when an application was run by configuring audit process tracking in Windows. The following links might get you started:
Audit process tracking
How can I track what programs come and go on my machine?
The process tracking will create entries in the Windows event log which you can then access using C++, C# &/or VB.Net. You can use these logs to see if the Parent application is running.
Edit:
If you have access to the C++ codebase you could try to catch the exception when the parent app crashes or closes, eg:
Application.ThreadException += new ThreadExceptionEventHandler(ApplicationThreadException);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(ApplicationUnhandledException);
private void ApplicationThreadException(object sender, ThreadExceptionEventArgs e)
{
//Write to a File, Registry, Database flagging the application has crashed
}
private void ApplicationUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
//Write to a File, Registry, Database flagging the application has crashed
}
private void frmMain_FormClosed(object sender, FormClosedEventArgs e)
{
//Write to a File, Registry, Database flagging the application has closed
}
Otherwise you will have to poll to see if the Parent application is listed in the Process Manager, eg:
StringBuilder sb = new StringBuilder();
ManagementClass MgmtClass = new ManagementClass("Win32_Process");
foreach (ManagementObject mo in MgmtClass.GetInstances())
{
sb.Append("Name:\t" + mo["Name"] + Environment.NewLine);
sb.Append("ID:\t" + mo["ProcessId"] + Environment.NewLine);
sb.Append(Environment.NewLine);
}
If its not listed, close the child application.

Firstly, you have to catch event when the parent windows raise exception or closing.
Secondly, you will send to close message to process which already launched by parent window.
For your information about send close message you can take reference here:
Send message to a Windows process (not its main window)
Or
how to close a window from a different process

Related

C# How to enable exit event on a running javaw app

I am trying to create an external launcher for an app, which I recently noticed is running in Java..
I did not immediately noticed because the program has an .exe extension and I assumed it was an executable directly running the software. Instead, it appears that this is an initial container than then open Java and run the software in Java.
The launcher I wrote works for apps like Notepad, but the structure I have does not work with the situation I have found myself in.
Here the (simplified) code I am using.
Button on a form launch the exe using this
MyProcess = Process.Start(processPath);
MyProcess.EnableRaisingEvents = true;
MyProcess is a process class with a private class associated to it. I got the code from another answer here.
private Process withEventsField_MyProcess;
Process MyProcess
{
get { return withEventsField_MyProcess; }
set
{
if (withEventsField_MyProcess != null)
{
withEventsField_MyProcess.Exited -= MyProcess_Exited;
}
withEventsField_MyProcess = value;
if (withEventsField_MyProcess != null)
{
withEventsField_MyProcess.Exited += MyProcess_Exited;
}
}
}
Whenever the event is triggered, I run my event code
private void MyProcess_Exited(object sender, System.EventArgs e)
{
//do stuff here
Application.Exit();
}
The problem with this is that I was planning to monitor an executable, and instead I find myself with an exe that stats java and then exits, and my events detects that as the exit event for the whole system.
I am trying to find a simple solution that allows me to detect when the specific Java app is closed so I can execute the rest of the program.
While I am writing this as a generic question for future users, I have the hint of an idea, but no clear view about how to implement it (assuming the idea is good at all).
I found out that via cmd I can get processes with also the command line executed to call them.
In the case of the Java program I want to monitor, the command line would work as a unique identifier. Therefore, I should be able to hook up into that to determine which process I want to monitor for the exited event.
And this is where I hit the wall.
Any help would be much appreciated.
Apparently, I did not google enough.
This is quite easy o achieve with WMI queries.
This code shows how one can isolate all the instances of the process javaw.exe and check any WMI parameter (e.g. the CommandLine)
public static void Main()
{
SelectQuery query = new SelectQuery("Select * from Win32_Process WHERE Name = 'javaw.exe'" );
ManagementScope scope = new System.Management.ManagementScope(#"\\.\root\CIMV2");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
try
{
foreach (ManagementObject processes in searcher.Get())
{
Console.WriteLine(processes["CommandLine"].ToString() + Environment.NewLine);
}
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e);
}
Console.Read();
}
Here a guide that shows how to create an event watcher base don WMI query
https://www.codeproject.com/Articles/12138/Process-Information-and-Notifications-using-WMI
It is an old post, and you will need to update part of the code.

How to detect when a user is adding or removing a program in WPF C#

My WPF app is like a MacBook dock which displays apps. I want to update the applications list within my app whenever the user installs or uninstalls a program.
What would be a good way to capture that add/remove program event?
As most people flagged for too broad I'm going to elaborate further:
I haven't tried anything yet. The only thing I'm thinking of is rescanning the registry every now and then to see if the program list has changed. This will work for sure, however, that's my backup option for now and I'm looking for a better solution.
By installed app I mean an application which has a registry key associated with it in either of these locations and therefore it shows up in the add/remove programs window.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall
By uninstalled app I mean - a program you uninstalled from the add/remove program window.
Solved it. When you add or remove a program(install/uninstall) Windows writes events in the Event Log(Event Viewer) under WindowsLogs/Application. You can listen to when a new log entry is added using EventLog.EntryWritten
EventLog eLog = new EventLog();
eLog.Log = "Application"; //MsiInstaller events are written in Application
eLog.EntryWritten += Log_NewInstallUninstallOccured; //Add the event and remove it when you want to stop listening
eLog.EnableRaisingEvents = true; // Enable event raising
private void Log_NewInstallUninstallOccured(object sender, EntryWrittenEventArgs e)
{
if (e.Entry.Source == "MsiInstaller") //MsiInstaller is the source responsible for installation related events
{
if(e.Entry.Message.Contains("Installation completed successfully."))
{
Console.WriteLine("Installation Occured");
}
else if (e.Entry.Message.Contains("Removal completed successfully."))
{
Console.WriteLine("Removal Occured");
} else
{
Console.WriteLine("Other Installation Event Occured");
}
}
}
Sources:
How to tell which user installed or uninstalled an app in Windows
EventLog Class
EventLog.EntryWritten Event

How to check a Window already opened when button is clicked?

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

How to reopen a file immediately after it closes via my C# application

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.

how to set focus and launch the already running application on button click event in c#.net3.5?

i have been trying the code using mutex but im unable to open my exe after button click
im successful in not making the multiple entries of the application on the taskbar at button click but my application is launched only when i close my form..
i want to launch my application on button click and if the application is already launched then i need to focus on the previous running application..
how could i able to resolve my need to launch as well as focusin and reopening that application again..
im sending u my code that im using on button click event and plz modify my errors...
coding at program.cs
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
System.Diagnostics.Process.Start("filename.exe");
}
:
coding done at form1.cs
private void button1_Click(object sender, EventArgs e)
{
try
{
bool createdNew;
Mutex m = new Mutex(true, "e-Recording", out createdNew);
System.Diagnostics.ProcessStartInfo f = new System.Diagnostics.ProcessStartInfo("C:\\windows\\system32\\rundll32.exe", "C:\\windows\\system32\\shimgvw.dll,ImageView_Fullscreen " + "filename.exe".TrimEnd(null));
if (createdNew) Launch();
else
{
MessageBox.Show("e-Recording is already running!", "Multiple Instances");
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
}
This is be able to find and switch to an already running process that matches what you are trying to start.
[DllImport( "user32.dll" )]
public static extern bool ShowWindowAsync( HandleRef hWnd, int nCmdShow );
public const int SW_RESTORE = 9;
public void SwitchToCurrent() {
IntPtr hWnd = IntPtr.Zero;
Process process = Process.GetCurrentProcess();
Process[] processes = Process.GetProcessesByName( process.ProcessName );
foreach ( Process _process in processes ) {
// Get the first instance that is not this instance, has the
// same process name and was started from the same file name
// and location. Also check that the process has a valid
// window handle in this session to filter out other user's
// processes.
if ( _process.Id != process.Id &&
_process.MainModule.FileName == process.MainModule.FileName &&
_process.MainWindowHandle != IntPtr.Zero ) {
hWnd = _process.MainWindowHandle;
ShowWindowAsync( NativeMethods.HRef( hWnd ), SW_RESTORE );
break;
}
}
}
I posted an answer a while back to a question about Delphi. I explained that I didn't have a background in Delphi but I described at a high level what I did in C# to build a component that uses InterProcess Communication (IPC) with .NET remoting to not only activate a running instance, but also forward the command line parameters from the second instance into the first instance. I linked to a pretty simple to use component that wraps all this functionality up. It may be useful to you.
Hers's my answer from the other question:
The best way to do this is actually in
the the startup code of your exe. In
other words, let Explorer launch a
second copy of the exe which then
proceeds to detect that it is already
running and have it send a message to
the running instance.
Personally, I have practically no
experience with Delphi, but the way I
did this in a .NET application was
using a mutex and an interprocess
communication channel.
The general idea was that the first
instance of the application would
start, and begin listening on an IPC
channel. It would also create a named
interprocess mutex. When the second
instance launched, it would be unable
to create the mutex of the same name
which meant that a previous instance
was running and listening for calls on
the IPC channel. The second instance
then sent the command line arguments
to the first instance over IPC and the
first instance took action on them.
The second instance then exits without
showing any UI.
I've uploaded the code for this
component (C#) and the link is below.
I don't believe it has any external
dependencies and I don't know what the
equivalent communication mechanism in
Delphi would be - but hopefully this
gives you some ideas.
InstanceManager Component (C#)
Note that usage of named mutexes is discouraged for security reasons. Any process (even one running under guest account) can create a mutex with the same name before your process was started. Solving these security problems is usually harder than just not using named mutex at all.
To solve your problem, you just need to store process handler or process ID and then look for a window with that process ID. This is similar to the way task manager works.

Categories

Resources