命令行-c#寄存器命令行参数don';t启动新实例

本文关键字:命令行 新实例 启动 实例 寄存器 -c# 参数 don | 更新日期: 2023-09-27 18:01:13

应用程序c:''pinkPanther.exe正在运行,它是我用c#编写的应用程序。其他一些应用程序启动了c:''pinkPanther.exe purpleAligator greenGazelle OrangeOrangutan,我不想用这些参数启动c:''pinkPanher.exe的新实例,但对当前运行的c:''pinkPanther.exe注册它并以某种方式对它做出反应。

怎么做?

编辑!!!:我很抱歉pinkPanther.exe和ruzovyJeliman.exe造成了混乱-我从我的母语翻译了这个问题,但错过了:(

命令行-c#寄存器命令行参数don';t启动新实例

这是假设你的应用程序是一个WinForms应用程序,因为这会让它更容易打开。这是一个非常简单的例子,但它将向您展示基本信息:

  1. 添加对Microsoft.VisualBasic的引用
  2. 创建一个继承自WindowsFormsApplicationBase的应用程序类。这个基类包含内置机制,用于创建单个实例应用程序,并使用新参数响应命令行上的重复调用:

    using Microsoft.VisualBasic.ApplicationServices;
    //omitted namespace
    public class MyApp : WindowsFormsApplicationBase {
        private static MyApp _myapp;
        public static void Run( Form startupform ) {
            _myapp = new MyApp( startupform );
            _myapp.StartupNextInstance += new Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventHandler( _myapp_StartupNextInstance );
            _myapp.Run( Environment.GetCommandLineArgs() );
        }
        static void _myapp_StartupNextInstance( object sender, Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs e ) {
            //e.CommandLine contains the new commandline arguments
            // this is where you do what you want with the new commandline arguments
            // if you want it the window to come to the front:
            e.BringToForeground = true;
        }
        private MyApp( Form mainform ) {
            this.IsSingleInstance = true;
            this.MainForm = mainform;
        }
    }
    
  3. Main()中,您所要更改的只是在新类上调用Run(),而不是Application.Run():

    static class Program {
        [STAThread]
        static void Main() {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault( false );
            MyApp.Run( new MyMainForm() );
        }
    }
    

WindowsFormsApplicationBase还有一些其他功能,您也可以探索。

要与应用程序的其他实例进行通信,需要某种进程间通信。显然,WCF是.Net中推荐的IPC形式。你可以用这样的代码(使用WPF,但WinForms会类似(来做到这一点:

[ServiceContract]
public interface ISingletonProgram
{
    [OperationContract]
    void CallWithArguments(string[] args);
}
class SingletonProgram : ISingletonProgram
{
    public void CallWithArguments(string[] args)
    {
        // handle the arguments somehow
    }
}
public partial class App : Application
{
    private readonly Mutex m_mutex;
    private ServiceHost m_serviceHost;
    private static string EndpointUri =
        "net.pipe://localhost/RuzovyJeliman/singletonProgram";
    public App()
    {
        // find out whether other instance exists
        bool createdNew;
        m_mutex = new Mutex(true, "RůžovýJeliman", out createdNew);
        if (!createdNew)
        {
            // other instance exists, call it and exit
            CallService();
            Shutdown();
            return;
        }
        // other instance does not exist
        // start the service to accept calls and show UI
        StartService();
        // show the main window here
        // you can also process this instance's command line arguments
    }
    private static void CallService()
    {
        var factory = new ChannelFactory<ISingletonProgram>(
            new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), EndpointUri);
        var singletonProgram = factory.CreateChannel();
        singletonProgram.CallWithArguments(Environment.GetCommandLineArgs());
    }
    private void StartService()
    {
        m_serviceHost = new ServiceHost(typeof(SingletonProgram));
        m_serviceHost.AddServiceEndpoint(
            typeof(ISingletonProgram),
            new NetNamedPipeBinding(NetNamedPipeSecurityMode.None),
            EndpointUri);
        m_serviceHost.Open();
    }
    protected override void OnExit(ExitEventArgs e)
    {
        if (m_serviceHost != null)
            m_serviceHost.Close();
        m_mutex.Dispose();
        base.OnExit(e);
    }
}