2011-04-27 146 views
1

我已成功地从StackOverflow上找到下面的代码:使用Microsoft.VisualBasic.ApplicationServices来管理应用程序的单一实例

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 
    } 

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

 #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 

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

回答

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 
    } 
+0

好吧,但我在哪里把我的应用程序逻辑代码(在我的问题的第三个代码)? – DoomerDGR8 2011-04-28 12:28:10

+0

你称之为Application Logic的代码看起来像你原来的Main()函数。保持这种方式。只需摆脱您添加的SingleInstance逻辑。 – 2011-04-28 13:11:01

+0

错误......我实际上是基于命令行参数启动不同的主窗体。你是否建议主函数不会在secon实例上重新执行?我称为Application Logic的代码块包含两行:Application.Run(新AppMDIRibbonDX());和Application.Run(新AppMDIRibbon());'我不希望我的'Application Logic'代码在'SingleInstanceApplication'(我的原始案例中的'SingleInstanceController')类中。 – DoomerDGR8 2011-04-28 14:01:42