使用Microsoft.VisualBasic.ApplicationServices来管理应用程序的单个实例

时间:2011-04-27 13:33:02

标签: c# .net winforms single-instance

我设法从StackOverflow中找到以下代码:

using Microsoft.VisualBasic.ApplicationServices;
using System.Windows.Forms;

namespace ExciteEngine2.MainApplication {

    public class SingleInstanceController: WindowsFormsApplicationBase {

        public delegate Form CreateMainForm();
        public delegate void StartNextInstanceDelegate(Form mainWindow);
        private readonly CreateMainForm formCreation;
        private readonly StartNextInstanceDelegate onStartNextInstance;

        public SingleInstanceController() {

        }
        public SingleInstanceController(AuthenticationMode authenticationMode)
            : base(authenticationMode) {

        }

        public SingleInstanceController(CreateMainForm formCreation, StartNextInstanceDelegate onStartNextInstance) {
            // Set whether the application is single instance
            this.formCreation = formCreation;
            this.onStartNextInstance = onStartNextInstance;
            IsSingleInstance = true;

            StartupNextInstance += this_StartupNextInstance;
        }

        private void this_StartupNextInstance(object sender, StartupNextInstanceEventArgs e) {
            if (onStartNextInstance != null) {
                onStartNextInstance(MainForm); 
                // This code will be executed when the user tries to start the running program again,
                // for example, by clicking on the exe file.
                // This code can determine how to re-activate the existing main window of the running application.
            }
        }

        protected override void OnCreateMainForm() {
            // Instantiate your main application form
            MainForm = formCreation();
        }

        //public void Run() {
        //  string[] commandLine = new string[0];
        //  base.Run(commandLine);
        //}

        protected override void OnRun() {
            base.OnRun();
        }

    }

}

我在Program.cs

中有这个
    private static Form CreateForm() {
        return new AppMDIRibbon();
    }

    private static void OnStartNextInstance(Form mainWindow)            
    {
        // When the user tries to restart the application again, the main window is activated again.
        mainWindow.WindowState = FormWindowState.Maximized;
    }

    [STAThread]
    static void Main(string[] args) {

        SingleInstanceController ApplicationSingleInstanceController = new SingleInstanceController(CreateForm, OnStartNextInstance);           
        ApplicationSingleInstanceController.Run(args);   

        #region Application Logic
        #endregion
    }

现在,我在Run()之前需要很多应用程序逻辑:

        #region Application Logic
        //Uninstall
        foreach (string arg in args) {
            if (arg.Split('=')[0] == "/u") {
                ApplicationLogger.Info("Uninstallation command received.");
                Process.Start(new ProcessStartInfo(Environment.GetFolderPath(Environment.SpecialFolder.System) + "\\msiexec.exe", "/x " + arg.Split('=')[1]));
                return;
            }
        }

        SetupXPO();
        SetupLogging();

        Thread.CurrentThread.CurrentCulture = new CultureInfo("en-GB");
        Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-GB");

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        Application.ThreadException += Application_ThreadException;

        try {
            ApplicationLogger.Info("Setting Telerik Theme: " + ConfigurationManager.AppSettings["ThemeToUse"]);
            ThemeResolutionService.ApplicationThemeName = ConfigurationManager.AppSettings["ThemeToUse"];

        }
        catch (Exception ex) {
            ApplicationLogger.Error("Exception while setting Telerik Theme.", ex);
            ThemeResolutionService.ApplicationThemeName = "ControlDefault";

        }

        DevExpress.UserSkins.OfficeSkins.Register();
        DevExpress.UserSkins.BonusSkins.Register();
        DevExpress.Skins.SkinManager.EnableFormSkins();
        DevExpress.Skins.SkinManager.EnableMdiFormSkins();

        if (args.Contains("/dx")) {
            Application.Run(new AppMDIRibbonDX());
            ApplicationLogger.Info("Application (DX) started.");

        }
        else {
            Application.Run(new AppMDIRibbon());
            ApplicationLogger.Info("Application started.");

        }
        #endregion

如何设置此逻辑?我正在使用命令行参数来实际启动备用表单。我正在使用命令行参数来导致卸载,并调用一些方法来设置数据库和日志记录。同样,我也在建立文化和主题。在实际应用程序运行之前所有这些。有人可以建议吗?

1 个答案:

答案 0 :(得分:2)

如果您简化了链接的Visual Basic派生类,则只需将当前调用替换为Application.Run()即可。这取决于您希望如何处理后续实例。

使用下面的版本,只需将您调用的:Application.Run(myForm)更改为SingleInstanceApplication.Run(myForm);

public sealed class SingleInstanceApplication : WindowsFormsApplicationBase
{
    private static SingleInstanceApplication _application;

    private SingleInstanceApplication()
    {
        base.IsSingleInstance = true;
    }

    public static void Run(Form form)
    {
        _application = new SingleInstanceApplication {MainForm = form};

        _application.StartupNextInstance += NextInstanceHandler;
        _application.Run(Environment.GetCommandLineArgs());
    }

    static void NextInstanceHandler(object sender, StartupNextInstanceEventArgs e)
    {
        // Do whatever you want to do when the user launches subsequent instances
        // like when the user tries to restart the application again, the main window is activated again.
        _application.MainWindow.WindowState = FormWindowState.Maximized;
    }
}

然后你的Main()方法包含你的“应用程序逻辑”

   [STAThread]
    static void Main(string[] args) {

        #region Application Logic
        //Uninstall
        foreach (string arg in args) {
            if (arg.Split('=')[0] == "/u") {
                ApplicationLogger.Info("Uninstallation command received.");
                Process.Start(new ProcessStartInfo(Environment.GetFolderPath(Environment.SpecialFolder.System) + "\\msiexec.exe", "/x " + arg.Split('=')[1]));
                return;
            }
        }

        SetupXPO();
        SetupLogging();

        Thread.CurrentThread.CurrentCulture = new CultureInfo("en-GB");
        Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-GB");

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        Application.ThreadException += Application_ThreadException;

        try {
            ApplicationLogger.Info("Setting Telerik Theme: " + ConfigurationManager.AppSettings["ThemeToUse"]);
            ThemeResolutionService.ApplicationThemeName = ConfigurationManager.AppSettings["ThemeToUse"];

        }
        catch (Exception ex) {
            ApplicationLogger.Error("Exception while setting Telerik Theme.", ex);
            ThemeResolutionService.ApplicationThemeName = "ControlDefault";

        }

        DevExpress.UserSkins.OfficeSkins.Register();
        DevExpress.UserSkins.BonusSkins.Register();
        DevExpress.Skins.SkinManager.EnableFormSkins();
        DevExpress.Skins.SkinManager.EnableMdiFormSkins();

        if (args.Contains("/dx")) {
            SingleInstanceApplication.Run(new AppMDIRibbonDX());
            ApplicationLogger.Info("Application (DX) started.");

        }
        else {
            SingleInstanceApplication.Run(new AppMDIRibbon());
            ApplicationLogger.Info("Application started.");

        }
        #endregion
    }