Запрещение пользователю запускать более одного экземпляра процесса
Я не опытный программист, поэтому любые советы / рекомендации / примеры будут оценены! У меня есть приложение формы Windows в C# (.Net Framework 4.5), которое заменяет службу Windows (возникли проблемы с переменной Session0). Приложение должно открыть процесс (я буду использовать Блокнот в качестве примера) и каждые 5 минут проверять, открыт ли Блокнот. Если Блокнот не открыт, приложение формы должно открыть его экземпляр. Приложение должно запретить пользователю открывать другой экземпляр Блокнота, если он уже открыт. Моя кодировка в настоящее время закрывает все экземпляры Блокнота. Мне просто нужно приложение, чтобы остановить открытие второго экземпляра Блокнота. Проблема в том, что пользователю вообще не разрешается взаимодействовать с приложением, как вы заметите в кодировке, пользователь даже не видит форму. Вот мое кодирование до сих пор:
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();
}
}
1 ответ
Заверните это в 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
}
Если вы хотите ограничить его одним экземпляром на машину, перед mutexId должен стоять префикс Global\