Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何运行c#WinForm应用程序的一个实例?_C#_Mutex_Single Instance - Fatal编程技术网

如何运行c#WinForm应用程序的一个实例?

如何运行c#WinForm应用程序的一个实例?,c#,mutex,single-instance,C#,Mutex,Single Instance,我有一个C#应用程序,它在启动时显示登录表单,并在用户经过身份验证后显示主表单。我使用互斥来限制我的应用程序只运行一个实例。而且,这只适用于登录表单。显示主表单后,它不会限制用户重新打开登录表单。我正在寻找一种解决方案,一旦主窗体打开,登录屏幕就无法显示 这是我的程序 [STAThread] static void Main() { bool mutexCreated=true; using (Mutex mutex = new Mutex(t

我有一个C#应用程序,它在启动时显示登录表单,并在用户经过身份验证后显示主表单。我使用互斥来限制我的应用程序只运行一个实例。而且,这只适用于登录表单。显示主表单后,它不会限制用户重新打开登录表单。我正在寻找一种解决方案,一旦主窗体打开,登录屏幕就无法显示

这是我的程序

 [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;
    }