аргумент командной строки c # register не запускает новый экземпляр - PullRequest
1 голос
/ 03 июля 2011

Приложение c: \ pinkPanther.exe запущено, и это приложение, которое я написал на c #.Некоторые другие приложения запускаются c: \ pinkPanther.exe purpleAligator greenGazelle OrangeOrangutan , и я не хотел бы запускать новый экземпляр c: \ pinkPanther.exe с этими аргументами, но для запущенного в данный момент c: \ pinkPanther.exe зарегистрировать его и как-то на него отреагировать.

Как это сделать?

РЕДАКТИРОВАТЬ !!!: я очень сожалею о pinkPanther.exeи ruzovyJeliman.exe, который вызвал путаницу - я перевел вопрос с моего родного языка и пропустил его: (

Ответы [ 2 ]

2 голосов
/ 03 июля 2011

Предполагается, что ваше приложение является приложением 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 имеет других возможностей , которые вы также можете исследовать.

1 голос
/ 03 июля 2011

Для связи с другим экземпляром приложения вам необходим какой-то тип межпроцессного взаимодействия.Очевидно, WCF является рекомендуемой формой IPC в .Net .Вы можете сделать это с помощью такого кода (используя 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);
    }
}
...