I am not an experienced programmer so any advice/guidance/examples would be appreciated! I have a windows form application in C# (.Net framework 4.5) that is replacing a windows service (issues with the Session0 variable were encountered). The application needs to open a process, (I'll be using Notepad as an example) and check every 5minutes whether Notepad is still open. If Notepad is not open, the form application must open an instance of it. The application must stop a user from opening another instance of Notepad, if it is already open. My coding currently closes all instances of Notepad. I simply need the application to stop a second instance of Notepad to be opened. The problem is that the user is not allowed to interact with the application at all, as you will note in the coding the user doesn't even see the form. Here is my coding thus far:
private void Form1_Load(object sender, EventArgs e)
{
this.ShowInTaskbar = false;
this.Visible = false;
//handle Elapsed event
myTimer.Tick += new EventHandler(OnElapsedTime);
//This statement is used to set interval to 5 minute (= 300,000 milliseconds)
myTimer.Interval = 60000;//300000;
//enabling the timer
myTimer.Enabled = true;
WatchForProcessStart("Notepad.exe");
}
private void OnElapsedTime(object source, EventArgs e)
{
bool status = IsProcessOpen("notepad");
if (status == true)
{
//TraceService("Notepad is already open" + DateTime.Now);
}
else
{
Process process = new Process();
process.StartInfo.FileName = "notepad.exe";
process.EnableRaisingEvents = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
process.Start();
//TraceService("Notepad opened" + DateTime.Now);
}
}
public bool IsProcessOpen(string procName)
{
System.Diagnostics.Process[] proc = System.Diagnostics.Process.GetProcessesByName(procName);
if (proc.Length > 0)
{
return true;
}
else
{
return false;
}
}
private ManagementEventWatcher WatchForProcessStart(string processName)
{
string queryString =
"SELECT TargetInstance" +
" FROM __InstanceCreationEvent " +
"WITHIN 10 " +
" WHERE TargetInstance ISA 'Win32_Process' " +
" AND TargetInstance.Name = '" + processName + "'";
// The dot in the scope means use the current machine
string scope = @"\\.\root\CIMV2";
// Create a watcher and listen for events
ManagementEventWatcher watcher = new ManagementEventWatcher(scope, queryString);
watcher.EventArrived += ProcessStarted;
watcher.Start();
return watcher;
}
private void ProcessStarted(object sender, EventArrivedEventArgs e)
{
ManagementBaseObject targetInstance = (ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value;
string processName = targetInstance.Properties["Name"].Value.ToString();
bool status = IsProcessOpen("notepad");
if (status == true)
{
System.Diagnostics.Process.Start("cmd.exe", "/c taskkill /IM notepad.exe");
}
else
{
Process process = new Process();
process.StartInfo.FileName = "notepad.exe";
process.EnableRaisingEvents = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
process.Start();
}
}
Wrap it up in a Mutex
var mutexId = "MyApplication";
using (var mutex = new Mutex(false, mutexId))
{
if (!mutex.WaitOne(0, false))
{
MessageBox.Show("Only one instance of the application is allowed!", "Info", MessageBoxButtons.OK, MessageBoxIcon.Hand);
return;
}
// Do scome work
}
If you want to restrict it to one instance per machine, the mutexId needs to be prefixed with Global\