在Winforms中具有外部命令行参数的SingleInstanceApp

时间:2017-06-27 06:38:52

标签: c# .net wpf winforms

我熟悉WPF应用程序,但对Winforms来说却是全新的。

目标是创建单个实例Winforms应用程序。如果另一个实例被实例化,它应该通过相应的命令args通知主实例,这些命令会调用主实例上的动作。以下是适用于WPF的sample

我使用MSDN helper在WPF中实现了相同的功能。但是当我尝试在Winforms中使用相同的东西时,我无法解决以下问题。

    Winforms中缺少
  • Application个实例。
  • 缺少
  • Application.Current将用于调用主实例。

在winforms中是否有任何等效物,或者在Winforms中实现类似功能的任何其他方式。

3 个答案:

答案 0 :(得分:1)

这个想法是使用Mutex来检测已经运行的实例。要与第一个实例通信,您可以使用IPC(进程间通信)。这是代码:

static class Program
{
    const string AppId = "Local\\1DDFB948-19F1-417C-903D-BE05335DB8A4"; // Unique par application 

    [STAThread]
    static void Main(string[] args)
    {
        using (var mutex = new Mutex(false, AppId))
        {
            if (!mutex.WaitOne(0))
            {
                // 2nd instance
                // Send the command line to the first instance
                IpcChannel clientChannel = new IpcChannel();
                ChannelServices.RegisterChannel(clientChannel, false);
                SingleInstance app = (SingleInstance)Activator.GetObject(typeof(SingleInstance), string.Format("ipc://{0}/RemotingServer", AppId));
                app.Execute(args);
                return;
            }

            // 1st instance

            // Register the IPC server
            IpcChannel channel = new IpcChannel(AppId);
            ChannelServices.RegisterChannel(channel, false);
            RemotingConfiguration.RegisterWellKnownServiceType(typeof(SingleInstance), "RemotingServer", WellKnownObjectMode.Singleton);

            // Start the application
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }

    private class SingleInstance : MarshalByRefObject
    {
        public void Execute(string[] args)
        {
            // TODO use the args sent by the second instance
        }
    }
}

答案 1 :(得分:0)

MSDN上的文档:https://msdn.microsoft.com/en-us/library/f55ddskf(v=vs.110).aspx

简短的方法

  • 在启动应用程序时,创建/打开具有唯一名称的互斥锁(它的范围是全局/系统

var mutex = new Mutex(false, "My awesome single-instance project");

  • 检查互斥锁是否已被控制/控制

var isMutexControlled = mutex.WaitOne(0, false);

  • 如果已经控制,请退出该应用程序。

要获得更深入的社区知识,请查看此答案,该答案提供了创建互斥锁的强大方法:What is a good pattern for using a Global Mutex in C#?

奖金Q& A

问:为什么Application或Application.Current不可用或为空?

答:WPF库中找不到System.Windows.Application.Current ,而不是Windows窗体库中。它们是构建视觉应用程序的独立框架(尽管它们可以组合在一起,但不要让它们落在那个兔子洞之外)。

答案 2 :(得分:0)

您可以像这样使用全局互斥锁: https://stackoverflow.com/a/1213517

或使用此答案中的Windows事件: https://stackoverflow.com/a/646500