1

I want to build a c# app - it should act like what skype does in the way that I create a link in a web page and it executes a "callto" action to the app passing it arguments. I want the app to be in the taskbar only.

So I fire up the app first time and then the next time I click the link it would execute again on the first application.

<a href="myapp:12345">Click me</a>

I'll set up the windows registry to respond accordingly then it should fire the app with the arguments

e.g. myapp.exe /12345

I can make the app work but every time I click the link I get a new instance, how do I pass the arguments to the currently running application?

user1320651
  • 808
  • 2
  • 15
  • 42
  • Have a look at [this](http://stackoverflow.com/questions/93989/prevent-multiple-instances-of-a-given-app-in-net) to prevent a second instance, for the passing of the argument you have to create a listener in the first app and a sender in the second. A named pipe can do that, or a file that is read by one and written by the other. – rene Jul 19 '13 at 17:46
  • how do i pass args to the currently running app? – user1320651 Jul 19 '13 at 17:47
  • ok, thanks, what type of listener should I use? args = Environment.GetCommandLineArgs(); – user1320651 Jul 19 '13 at 17:52
  • I was using static void Main(string[] MyArgs) – user1320651 Jul 19 '13 at 17:53
  • A TCP Server is the easiest because it comes with aync behaviour – rene Jul 19 '13 at 17:54
  • http://stackoverflow.com/questions/1685005/single-instance-app-with-message-passing-via-cmd-line – user1320651 Jul 19 '13 at 17:56
  • Would you be able to kick me in the right direction with some code? – user1320651 Jul 19 '13 at 17:57
  • http://stackoverflow.com/questions/3545766/sending-arguments-to-an-app-instance-that-resides-in-another-process – user1320651 Jul 19 '13 at 17:59

1 Answers1

1

Inspired on this for preventing a second instance and this for the namedpipeserver

static void Main(string[] args)
{

    string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value.ToString();

    // unique id for global mutex - Global prefix means it is global to the machine
    string mutexId = string.Format("Global\\{{{0}}}", appGuid);

    using (var mutex = new Mutex(false, mutexId))
    {

        var hasHandle = false;
        try
        {
            try
            {
                hasHandle = mutex.WaitOne(5000, false);
            }
            catch (AbandonedMutexException)
            {
                hasHandle = true;
            }


            if (hasHandle)
            {
                // main app
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Form1 frm = new Form1();

                HandleArgs(args,frm); // handle first start with args

                Server(appGuid, frm); // handle next clients

                Application.Run(frm);
            }
            else
            {
                //any next client..
                var cli = new NamedPipeClientStream(appGuid);
                // connect to first app
                cli.Connect();
                // serialiaze args and send over
                var bf = new BinaryFormatter();
                bf.Serialize(cli, args);  // the commandline args over the line
                cli.Flush();
                cli.Close();
                // done
            }
        }
        finally
        {
            if (hasHandle)
                mutex.ReleaseMutex();
        }
    }
}

// do usefull stuff with the commandline args
static void HandleArgs(string[] args, Form1 frm)
{
    foreach (var s in args)
    {
        // just append the args to the textbox
        frm.textBox1.Text += s;
        frm.textBox1.Text += Environment.NewLine;
    }
}

// server that runs async
static void Server(string appGuid, Form1 frm)
{
    var srv = new NamedPipeServerStream(appGuid, PipeDirection.InOut, 5, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);

    srv.BeginWaitForConnection(state =>
    {
        NamedPipeServerStream nps = (NamedPipeServerStream)state.AsyncState;
        nps.EndWaitForConnection(state);

        var bf = new BinaryFormatter();
        string[] args = (string[])bf.Deserialize(nps);

        // don't forget to call on the UI thread
        frm.Invoke(new MethodInvoker(() => { HandleArgs(args, frm); }));

        nps.Disconnect();

        Server(appGuid, frm); // restart server
    }, srv);
}
Community
  • 1
  • 1
rene
  • 41,474
  • 78
  • 114
  • 152