0

I have created a single instance application using VisualBasic.dll but there are some situations where I need to create multiple instances. I needed single instance behavior to handle the context menu behavior where each windows context menu command will invoke a new instance of the application. I still need some context menus to load a another instance. I solved this by creating a new application context and running it on a new thread.

Sample code

var thread = new Thread(() => ThreadOpenFile(args));
thread.TrySetApartmentState(ApartmentState.STA);
thread.Start();

Thread content

private static void ThreadOpenFile(string[] args)
{
  ApplicationContext appCnxt= new ApplicationContext(new newForm(args[1]));
  Application.Run(appCnxt);            
}

I its same as

private static void ThreadOpenFile(string[] args)
{
  Application.Run(new newForm(args[1]));            
}

This will create a new ApplicationContext, ThreadContext and the new form and Application.Run will link ThreadContext to the ApplicationContext just like starting a new application. I cannot find any documentation explaining what happens and who is managing this "new Thread" I am creating. If I try to start a new process it will invoke single instance handler

protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs)

of VisualBasic.dll and go in a recursive loop forever as expected. I want to know whether this is the right approach or is there a better way ?

This link shows how to use application context to hook a Splash screen behavior. If there are good references I can find the internals is also appreciated.

Krv Perera
  • 119
  • 2
  • 15
  • Don't do this. Use the Startup event, simply set Me.SingleInstance back to False if you decide you don't want a single instance. – Hans Passant Feb 11 '16 at 08:15
  • @HansPassant I understand all are now threads under the same process. I am doing it on C#. Like to know why you are saying "Don't do this" . I tried the suggestion but it seems I cannot change it on run-time second instance will wait for the first one (instantiated as a single instance) to close then start the new process until it will always invoke**OnStartupNextInstance** event . I think Visual Basic App Model uses a mutex kind of internal structure. I want to run a instance (instantiated as a single instance) and another instance as a new process (instantiated as a different process). – Krv Perera Feb 11 '16 at 09:20
  • 1
    "Don't do this" because you'll shoot your leg off. You'll forget Application.EnableVisualStyles() and Application.SetUnhandledExceptionMode(). Like you did. And you're apt to invoke the horrors of getting the SystemEvents class to fire its events on the wrong thread, excessively hard to diagnose. Letting the app start but wait on the 1st process is rather a bad idea. What if the user starts it a 3rd or 4th time? Or nth time, furiously banging on the shortcut because "it is not working"? WindowsFormsApplicationBase does not help you do that, you'll have to cook your own. – Hans Passant Feb 11 '16 at 09:29
  • Simply I want my application to aggregate command line arguments from instances when I right click and invoke a command on multiple files and create a single instance and should create multiple instances when called on single files. Do you know a better approach for this, my only option is IPC at the moment then. – Krv Perera Feb 11 '16 at 09:38
  • Heck of an XY question. "Aggregating" is already supported, your 1st instance gets the StartupNextInstance event, its e.CommandLine property contains the new commands. – Hans Passant Feb 11 '16 at 09:44

1 Answers1

0

Accepting the answer by @HansPassant on comments.

You'll forget Application.EnableVisualStyles() and Application.SetUnhandledExceptionMode(). Like you did. And you're apt to invoke the horrors of getting the SystemEvents class to fire its events on the wrong thread, excessively hard to diagnose. Letting the app start but wait on the 1st process is rather a bad idea. What if the user starts it a 3rd or 4th time? Or nth time

Krv Perera
  • 119
  • 2
  • 15