4

起動時にログインフォームを表示し、ユーザーが認証された後にメインフォームを表示する C# アプリケーションがあります。Mutex を使用して、アプリケーションのインスタンスを 1 つだけ実行するように制限しました。そして、これはログインフォームでのみうまく機能します。メイン フォームが表示されると、ユーザーがログイン フォームを再び開くことは制限されません。メインフォームが既に開いているとログイン画面が表示されないという解決策を探していました。

これが私のProgram.csです

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

4 に答える 4

7

私はいくつかの小さな変更を加えました:


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内部から作成しないことにしましたLogin(これは、アプリケーションがどのように機能するかを信じています)。代わりに、パラメーターをに渡しますMainLoginまた、プロパティを持つようにいくつかの小さな変更を加えましたUserName(と同じMain)。

于 2012-09-10T05:18:13.280 に答える
0

Microsoft.VisualBasic への参照に問題がなければ、その SingleInstance 処理を使用できます。

    [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());
    }
}
于 2012-09-09T15:07:48.173 に答える
-1

のインスタンスを 1 つだけに制限したい場合はForm、次のようにすることができます。

public static class LoginForm 
{
    private static Form _loginForm = new Form();


    public static bool ShowLoginForm(){

        if(_loginForm.Visible)
             return false;

        _loginForm.Show();
        return true;
    }
}

そのため、複数のクライアントがこのメソッドを呼び出す場合、これはログイン フォームを表示するための唯一のメソッドであり、既に表示されている場合は実行されません。

于 2012-09-09T14:47:33.427 に答える
-2
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;
    }
于 2013-07-09T14:07:53.297 に答える