如何运行c#WinForm应用程序的一个实例?
我有一个C#应用程序,它在启动时显示登录表单,并在用户经过身份验证后显示主表单。我使用互斥来限制我的应用程序只运行一个实例。而且,这只适用于登录表单。显示主表单后,它不会限制用户重新打开登录表单。我正在寻找一种解决方案,一旦主窗体打开,登录屏幕就无法显示 这是我的程序如何运行c#WinForm应用程序的一个实例?,c#,mutex,single-instance,C#,Mutex,Single Instance,我有一个C#应用程序,它在启动时显示登录表单,并在用户经过身份验证后显示主表单。我使用互斥来限制我的应用程序只运行一个实例。而且,这只适用于登录表单。显示主表单后,它不会限制用户重新打开登录表单。我正在寻找一种解决方案,一旦主窗体打开,登录屏幕就无法显示 这是我的程序 [STAThread] static void Main() { bool mutexCreated=true; using (Mutex mutex = new Mutex(t
[STAThread]
static void Main()
{
bool mutexCreated=true;
using (Mutex mutex = new Mutex(true, "eCS", out mutexCreated))
{
if (mutexCreated)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Login());
}
else
{
Process current = Process.GetCurrentProcess();
foreach (Process process in Process.GetProcessesByName(current.ProcessName))
{
if (process.Id != current.Id)
{
XtraMessageBox.Show("Another instance of eCS is already running.", "eCS already running", MessageBoxButtons.OK, MessageBoxIcon.Information);
SetForegroundWindow(process.MainWindowHandle);
break;
}
}
}
}
}
如果希望将
表单
的实例限制为一个,可以执行以下操作:
public static class LoginForm
{
private static Form _loginForm = new Form();
public static bool ShowLoginForm(){
if(_loginForm.Visible)
return false;
_loginForm.Show();
return true;
}
}
因此,如果多个客户端将调用此方法(这是显示登录表单的唯一可能的方法),在其已可见的情况下,将不会执行此方法。如果您对Microsoft.VisualBasic的引用感到满意,则可以使用其单实例处理
[STAThread]
static void Main(string[] args)
{
using (System.Threading.Mutex mutex = new System.Threading.Mutex(true, "MyApp.SingleInstance.Mutex", out createdNew))
{
MainForm = new MainDlg();
SingleInstanceApplication.Run(MainForm, StartupNextInstanceEventHandler);
}
}
public static void StartupNextInstanceEventHandler(object sender, StartupNextInstanceEventArgs e)
{
MainForm.Activate();
}
public class SingleInstanceApplication : WindowsFormsApplicationBase
{
private SingleInstanceApplication()
{
base.IsSingleInstance = true;
}
public static void Run(Form f, StartupNextInstanceEventHandler startupHandler)
{
SingleInstanceApplication app = new SingleInstanceApplication();
app.MainForm = f;
app.StartupNextInstance += startupHandler;
app.Run(Environment.GetCommandLineArgs());
}
}
我做了一些小改动:
namespace CSMutex
{
static class Program
{
[STAThread]
static void Main()
{
bool mutexCreated=true;
using(Mutex mutex = new Mutex(true, "eCS", out mutexCreated))
{
if (mutexCreated)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Login loging = new Login();
Application.Run(loging);
Application.Run(new Main() { UserName = loging.UserName });
}
else
{
Process current = Process.GetCurrentProcess();
foreach (Process process in Process.GetProcessesByName(current.ProcessName))
{
if (process.Id != current.Id)
{
MessageBox.Show("Another instance of eCS is already running.", "eCS already running", MessageBoxButtons.OK, MessageBoxIcon.Information);
//SetForegroundWindow(process.MainWindowHandle);
break;
}
}
}
}
}
}
}
这与预期一样有效-即,即使当登录
表单关闭(并且主应用程序表单启动)时,也不允许用户再次运行应用程序。
我决定不从Login
中创建Main
(我相信应用程序就是这样工作的),而是将参数传递给Main
。
我还对
Login
做了一些小改动,因此它有UserName
propert(与Main
相同)。因此您无法控制允许用户做什么和不做什么?我假设一定有一些按钮或其他方式,用户可以通过这些按钮或其他方式重新打开登录屏幕。为什么不删除它们呢?将代码从登录表单移动到Program.csHans Passant中的Main()方法,my Program.cs应该启动登录窗口。我的代码已经在Program.cs中,但不起作用。代码如下:感谢Tigran的快速响应。登录表单(第一次)运行良好。问题是限制登录在主窗体已经运行后不打开。@user758961:如果你使用答案中给出的包装器,你实际上可以做到这一点。在适当的时候调用showloginfo(..)
。@user758961:您可以将其扩展到CloseLoginForm(..)
,或者在登录表单本身中使用此技巧。这仍然会保持先显示登录表单吗?这是您的主要方法,因此,它将阻止在第二个实例上加载您正在使用的任何启动对象。这仅适用于VB吗?我在使用c#winform我在我的c#程序中使用这种技术。您需要添加对Microsoft.VisualBasic程序集的引用。我很好奇为什么要使用for循环来检查else语句中的进程,为什么不只显示信息消息?
private bool IsSingleInstance()
{
string szCurrentProcessName = this.ProductName;
Process[] processlist = Process.GetProcesses();
foreach(Process theprocess in processlist)
{
string szProcessName = theprocess.MainModule.ModuleName.ToString();
if (szProcessName.Contains(szCurrentProcessName))
return false;
}
return true;
}