c# register commandline argument don't start n

2019-05-30 16:15发布

Application c:\pinkPanther.exe is running and it is application i wrote in c#. Some other application starts c:\pinkPanther.exe purpleAligator greenGazelle OrangeOrangutan and i would like not to start new instance of c:\pinkPanther.exe with these arguments, but to currently running c:\pinkPanther.exe register it and react to it somehow.

How to do it?

EDIT!!!: i'm very sorry about pinkPanther.exe and ruzovyJeliman.exe that caused the confusion - i translated question from my native language and missed it :(

2条回答
叛逆
2楼-- · 2019-05-30 16:20

This is assuming your application is a WinForms app, as that will make it easier to keep it open. This is a very simple example, but it will show you the basics:

  1. Add a reference to Microsoft.VisualBasic.
  2. Create an Application class inheriting from WindowsFormsApplicationBase. This base class contains built-in mechanisms for creating a single-instance application and responding to repeated calls on the commandline with new arguments:

    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. All you have to change in Main() is call Run() on your new class rather than Application.Run():

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

WindowsFormsApplicationBase has some other capabilities you can explore, as well.

查看更多
冷血范
3楼-- · 2019-05-30 16:24

To communicate with the other instance of the application, you need some sort of inter-process communication. Apparently, WCF is the recommended form of IPC in .Net. You can do that with code like this (using WPF, but WinForms would be similar):

[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);
    }
}
查看更多
登录 后发表回答