Click here to Skip to main content
16,021,823 members
Please Sign up or sign in to vote.
3.00/5 (1 vote)
See more:
I have a VB.NET program that I have written that I want to run in the system tray and process attachments they are opened from e-mails. I created my own file type and registered it in the registry. Everything works good except I don't know how on the second file that I'm processing to open it up in the already open program. I know how to check to see if there is another instance running but I don't know to turn control over to the already open program. Is there a way to direct the open to the program that is already running?

Thanks
Posted

There is a number of methods.

First method is the simplest works if you don't care about the same program located somewhere else on your disk(s), because — how would you know this is exactly the same? If you entry assembly is not strong named, all other assembly attributes does not provide reliable identification to tell is the assembly in different directory is the "same application" as the one you're running. So, let's assume you want to detect a second instance of the same application which has the same main module of its entry assembly with the same full file name. Also, a match in the properties of the process can be used (see below). To find this module file and process instance for currently running application, do the following:

C#
string mainModuleFile = System.Reflection.Assembly.GetEntryAssembly().Location;
System.Diagnostics.Process currentProcess = System.Diagnostics.Process.GetCurrentProcess();


Now, let's take care about first instance if it is already running. First, iterate all processes in the system using System.Diagnostics.Process.GetProcesses. For each process in the iteration loop, find its main module using Process.MainModule instance property. This property returns the instance of the class System.Diagnostics.ProcessModule, and System.Diagnostics.ProcessModule.FileName give you the full-path file name to compare with the one of your process you're currently running. If you have a match, the instance running this code is not the first. You can take required actions and exit the application.

In principle, this method can be modified to use a little bit different criterion for the match, using additional Process properties but not requiring exact match of the full path name; the properties like ProcessName, Modules, MainWindowTitle (if applicable), MainModule.ProcessName, etc.; in this way, a previous instance of the "same" application can be detected even if its executable file(s) is different. Again, no combination of the process properties can guarantee this is the "same" application.

This is not all…

To be continued…



—SA
 
Share this answer
 
v2

…continued from the previous Answer: advanced methods



Another group of methods used to detect the previous instance of the application is inter-process communication (IPC). It should be understood that different processes running the same applications are still different processes, perfectly isolated from each other, so IPC is the only way to communicate between them.

Why using IPC? The method described in my previous Answer is robust enough and some lack in performance is easily justified by the fact that second instance of the same application is no loaded often. It should be remembered, that IPC primitives shared between different processes should use some unique string anyway. I described one example of string which is certainly unique — a full path name of the main entry assembly module. For IPC, taking into account that process are started from the same application, some GUID can be used, which gives almost 100% (but not strictly 100%) uniqueness.

The real need in IPC comes when detection of previous along is not the only purpose. On typical example of IPC is the requirement to pass some data from the second instance to the fist one; and the typical example of such data is the list of file names passed to the second instance in its command line parameters. In native Windows application, different IPC primitive can be used, but for .NET the best IPC is named pipes, because the named pipe transport can be implemented using .NET remoting or WPF (self-hosting).

The same pipe can be used for detection of the previous instance (failure to connect means that the currently running instance if the first one; previous instance does not exist) and for transport of data between the second instance and the first one.

—SA
 
Share this answer
 
Comments
Espen Harlinn 13-Mar-11 6:27am    
Good points - I would probably go for a memory mapping and event objects - but the end result would be about the same :)
Sergey Alexandrovich Kryukov 13-Mar-11 12:52pm    
Thank you Espen,
I collectively mentioned memory mapping and even objects under "IPC".
Remoting creates different IPC primitive (named pipe), but under the scene which makes the code very short yet robust.
--SA
Espen Harlinn 13-Mar-11 13:40pm    
I guessed that, but I'm not sure it was clear to the OP :)
Sergey Alexandrovich Kryukov 13-Mar-11 14:56pm    
Agree, agree... let's say, I already spend too much time in two Answers, now feel a bit greedy about using my own time...
--SA
Easy. Read this[^].
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 13-Mar-11 12:56pm    
Dave, this is indeed very easy, so it could be the best Answer for OP, but only if System.Windows.Forms is involved, which is not the fact. This is the only problem: this solution isn't universal. My 4.
-SA
Dave Kreskowiak 13-Mar-11 18:23pm    
He wasn't very clear about what he's doing or dealing with, so instead of writing a book that covers all bases, I gave him the most logical answer based on the most probable assumption. He's writing a VB.NET app that has to take parameters from a second instance of the same app.

If this isn't what he wants, he can reply with more specific information.
Sergey Alexandrovich Kryukov 13-Mar-11 18:32pm    
That's true; I only say I provide the answers not depending on any other factors except those I already know from the Question. Also, the fact that OP has the application is the system tray eliminated the need for showing first-instance application on top (which depends on the library but the comprehensive solution would need P/Invoke anyway).
--SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900