c# - studio - ¿Cómo puedo evitar lanzar mi aplicación varias veces?
publicar aplicacion windows forms (10)
Al iniciar su aplicación, main siempre llama a Application.Run()
. Busque en su método STAThread-Main y antes de la prueba Application.Run
, si hay instancias en ejecución de su archivo .exe.
Process p = Process.GetProcesses();
//check for your .exe
Vea this publicación aquí.
Desplegué mi aplicación C # WinForms usando la instalación ClickOnce. Todo funciona bien con eso (después de mucho trabajo) :), pero ahora estoy enfrentando un problema:
Cada vez que hago clic en el acceso directo de la aplicación en el menú Inicio, se inicia una nueva instancia. Necesito evitar esto.
¿Qué puedo hacer para evitar múltiples lanzamientos?
Al inicio del programa, compruebe si ya se está ejecutando el mismo proceso:
using System.Diagnostics;
static void Main(string[] args)
{
String thisprocessname = Process.GetCurrentProcess().ProcessName;
if (Process.GetProcesses().Count(p => p.ProcessName == thisprocessname) > 1)
return;
}
En WPF, puede usar este código en su archivo App.xaml.cs
:
private static System.Threading.Mutex _mutex = null;
protected override void OnStartup(StartupEventArgs e)
{
string mutexId = ((System.Runtime.InteropServices.GuidAttribute)System.Reflection.Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(System.Runtime.InteropServices.GuidAttribute), false).GetValue(0)).Value.ToString();
_mutex = new System.Threading.Mutex(true, mutexId, out bool createdNew);
if (!createdNew) Current.Shutdown();
else Exit += CloseMutexHandler;
base.OnStartup(e);
}
protected virtual void CloseMutexHandler(object sender, EventArgs e)
{
_mutex?.Close();
}
Hay un tema muy bueno en esa materia. Lo puedes encontrar aquí: odetocode.com/blogs/scott/archive/2004/08/20/… .
Hay veces que **Mutex**
no funciona en algunas áreas. Como usar en la aplicación de consola. Así que intenté usar WMI Query .
Intenta esto y funcionará.
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
if (!isStillRunning())
{
Application.Run(new Form1());
}
else {
MessageBox.Show("Previous process still running.",
"Application Halted", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
Application.Exit();
}
}
//***Uses WMI Query
static bool isStillRunning() {
string processName = Process.GetCurrentProcess().MainModule.ModuleName;
ManagementObjectSearcher mos = new ManagementObjectSearcher();
mos.Query.QueryString = @"SELECT * FROM Win32_Process WHERE Name = ''" + processName + @"''";
if (mos.Get().Count > 1)
{
return true;
}
else
return false;
}
Espero eso ayude.
Solución en la aplicación de formulario de Windows Prohibir nuevamente ejecutar la aplicación (reabrir la aplicación).
1- Primero agrega Class RunAlready.cs
2-Método CallIsRunning () con proceso de nombre de RunAlready.cs en Program.cs
Program.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Tirage.MainStand
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
PublicClass.Class.RunAlready RunAPP = new PublicClass.Class.RunAlready();
string outApp = RunAPP.processIsRunning("Tirage.MainStand");
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
MainStand_FrmLogin fLogin = new MainStand_FrmLogin();
if (outApp.Length == 0)
{
if (fLogin.ShowDialog() == DialogResult.OK)
{
Application.Run(new MainStand_masterFrm());
}
}
else MessageBox.Show( "Instance already running");
}
}
}
clase RunAlready:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PublicClass.Class
{
public class RunAlready
{
public string processIsRunning(string process)
{
string xdescription = "";
System.Diagnostics.Process[] processes =
System.Diagnostics.Process.GetProcessesByName(process);
foreach (System.Diagnostics.Process proc in processes)
{
var iddd = System.Diagnostics.Process.GetCurrentProcess().Id;
if (proc.Id != System.Diagnostics.Process.GetCurrentProcess().Id)
{
xdescription = "Application Run At time:" + proc.StartTime.ToString() + System.Environment.NewLine;
xdescription += "Current physical memory : " + proc.WorkingSet64.ToString() + System.Environment.NewLine;
xdescription += "Total processor time : " + proc.TotalProcessorTime.ToString() + System.Environment.NewLine;
xdescription += "Virtual memory size : " + proc.VirtualMemorySize64.ToString() + System.Environment.NewLine;
}
}
return xdescription;
}
}
}
Usa este código:
[STAThread]
static void Main()
{
using(Mutex mutex = new Mutex(false, "Global//" + appGuid))
{
if(!mutex.WaitOne(0, false))
{
MessageBox.Show("Instance already running");
return;
}
Application.Run(new Form1());
}
}
Usar Mutex
es el camino a seguir, ya que adivinar los nombres de los procesos está lleno de fallas y errores. Echa un vistazo a esta muy buena odetocode.com/blogs/scott/archive/2004/08/20/…
lo que siempre estoy usando es
bool checkSingleInstance()
{
string procName = Process.GetCurrentProcess().ProcessName;
// get the list of all processes by that name
Process[] processes = Process.GetProcessesByName(procName);
if (processes.Length > 1)
{
return true;
}
else
{
return false;
}
}
if (Process.GetProcesses().Count(p => p.ProcessName == "exe name") > 1)
{
foreach (var process in
Process.GetProcessesByName("exe name"))
{
process.Kill();
}
}