Использование Microsoft.VisualBasic.ApplicationServices для управления единственным экземпляром приложения
Мне удалось найти следующий код из Stackru:
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 ответ
Если вы упростите связанный с 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
}