Как убедиться, что запущен один экземпляр приложения
-
23-08-2019 - |
Вопрос
Я хочу проверить, когда пользователь дважды щелкает значок приложения, что ни один другой экземпляр этого приложения еще не запущен.
Я прочитал о My.Application, но до сих пор не знаю, что делать.
Решение
Наиболее распространенным шаблоном для этого является использование шаблона Singleton.Поскольку вы не указали язык, я предполагаю, что вы здесь имеете в виду C#, а если нет, то принципы в большинстве объектно-ориентированных языков остаются теми же.
Этот статья должна вам помочь.
Другие советы
Это то, что я использовал...(С# в .NET 2.0)
[STAThread]
private static void Main(string[] args)
{
//this follows best practices on
//ensuring that this is a single instance app.
string mutexName = "e50cf829-f6b9-471e-8d9f-67eac3699f09";
bool grantedOwnership;
//we prefix the mutexName with "Local\\" to allow this to run under terminal services.
//The "Local\\" prefix forces this into local user space.
//If we want to forbid this in TS, use the "Global\\" prefix.
Mutex singleInstanceMutex = new Mutex(true, "Global\\" + mutexName, out grantedOwnership);
try
{
if (!grantedOwnership)
{
MessageBox.Show("Error: X is already running.\n\nYou can only run one copy of X at a time.", "X", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
Application.Exit();
}
else
{
Application.Run(new X(args));
}
}
finally
{
singleInstanceMutex.Close();
}
}
В VB .NET есть IsSingleInstance логическое свойство, которое сделает всю работу за вас.
В VB (взято из здесь):
Public Class Program
Inherits Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase
Public Sub New()
Me.IsSingleInstance = True
End Sub
End Class
Вот как вы используете его в C# (взято из здесь):
// SingleInstanceApplication.cs
class SingleInstanceApplication : WindowsFormsApplicationBase {
// Must call base constructor to ensure correct initial
// WindowsFormsApplicationBase configuration
public SingleInstanceApplication() {
// This ensures the underlying single-SDI framework is employed,
// and OnStartupNextInstance is fired
this.IsSingleInstance = true;
}
}
// Program.cs
static class Program {
[STAThread]
static void Main(string[] args) {
Application.EnableVisualStyles();
SingleInstanceApplication application =
new SingleInstanceApplication();
application.Run(args);
}
}
Обязательно укажите ссылку на Microsoft.VisualBasic.dll в своем проекте.
Откройте свойства проекта (вкладка «Приложение») и проверьте Создать одноэкземплярное приложение вариант.
На вкладке «Приложение» вы также можете нажать кнопку Просмотр событий приложения кнопку, чтобы создать ПриложениеEvents.vb класс, в котором вы можете обработать событие второго экземпляра:
Partial Friend Class MyApplication
Private Sub MyApplication_StartupNextInstance(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs) Handles Me.StartupNextInstance
' Bring First Instance to Foreground
e.BringToForeground = True
' Pass Second Instance Command Line to First Instance
AppShared.DoSomethingWithCommandLine(e.CommandLine)
End Sub
End Class
У Скотта Хансельмана есть хорошая статья на эту тему.Код написан на C#, но я думаю, его будет легко перенести на VB.
Вот еще одна статья по этой теме на случай, если она не удовлетворит ваши потребности:
В VB.NET приложение с одним экземпляром просто флажок на странице свойств проекта.Вы также можете поймать My.Application.StartupNextInstance событие, чтобы ваш единственный экземпляр что-то делал при запуске другой копии.Это можно использовать, например, для MDI-подобного поведения при открытии запрошенного документа в исходном экземпляре.
За кулисами это инкапсулирует значительную часть мьютекса и IPC-слизи — см. WindowsFormApplicationBase - и также может использоваться из C#.
Благодаря приведенным выше советам я узнал, как сделать мое приложение единственным экземпляром, но мне все равно пришлось перейти на другой сайт, чтобы ТОЧНО узнать, как это сделать.Вот простая картинка, как мне это удалось сделать.Это было легко, и я надеюсь, что это поможет другим с такой же потребностью, потому что я уверен, что ОП решил эту проблему 7 лет назад:
Использовать Mutex
.По сути, Mutex
может быть назван строкой и уникален в среде CLR.
Образец кода:
try
{
mutex = Mutex.OpenExisting(mutexName);
//since it hasn’t thrown an exception, then we already have one copy of the app open.
MessageBox.Show(”A copy of Todo 3.0 is already open. Please check your system tray (notification area).”,
“Todo 3.0″, MessageBoxButtons.OK, MessageBoxIcon.Information);
Environment.Exit(0);
}
catch (Exception Ex)
{
//since we didn’t find a mutex with that name, create one
Debug.WriteLine(”Exception thrown:” + Ex.Message + ” Creating a new mutex…”);
mutex = new Mutex(true, mutexName);
}
Из этого почта:
Если ваше приложение создано на VB.NET 2.0–3.5, самый простой способ сохранить работающий единственный экземпляр программы — использовать «Свойства платформы приложений Windows».Чтобы попасть туда, щелкните правой кнопкой мыши имя вашего проекта и выберите «Свойства».После этого установите флажок «Создать одноэкземплярное приложение».
Вы также можете использовать файл ApplicationEvents.vb, чтобы показать пользователю, что он запустил вашу программу во второй раз.Вы можете легко создать/просмотреть это в том же окне свойств, нажав кнопку «Просмотр событий приложения».Внутри вы можете выбрать подменю MyApplication_StartupNextInstance и ввести туда код, например:
Private Sub MyApplication_StartupNextInstance(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs) Handles Me.StartupNextInstance
MessageBox.Show("This program is already running. If you do not see the program running, please check your " _
& "Windows Task Manager for this program name in the 'Processes' Tab." & vbNewLine & vbNewLine & "WARNING: " _
& " If you terminate the process, you will terminate the only instance of this program!", My.Application.Info.ProductName.ToString _
& " is Running!", MessageBoxButtons.OK, MessageBoxIcon.Warning)
End Sub
Позвольте мне знать, если это помогает!JFV
Назначьте своему приложению уникальный идентификатор, например жестко закодированное руководство, и создайте экземпляр Mutex, в котором вы назначите мьютексу этот идентификатор.Если выдается исключение, то это означает, что ваше приложение уже запущено (поскольку ему удалось создать мьютекс)
Я подумал, что будет проще разместить образец прямо здесь, а не ссылку.
[STAThread]
static void Main()
{
if (!IsAppAlreadyRunning())
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1()); /* Change Form1 for your main Form */
}
else
{
MessageBox.Show("Application is already running!");
}
}
public static bool IsAppAlreadyRunning()
{
Process currentProcess = Process.GetCurrentProcess();
return (IsAppAlreadyRunning(currentProcess.Id,
currentProcess.ProcessName));
}
private static bool IsAppAlreadyRunning(int ID, string Name)
{
bool isAlreadyRunning = false;
Process[] processes = Process.GetProcesses();
foreach (Process process in processes)
{
if (ID != process.Id)
{
if (Name == process.ProcessName)
{
isAlreadyRunning = true;
break;
}
}
}
return isAlreadyRunning;
}