After playing around with a new Windows Form project, I discovered that when you associate a file type with an executable in Windows, you can find the file path of the file that launched the application using args[0]
from static void Main(string[] args)
Is it possible to launch an event on your application when you double click a file if your application is already open? (As obviously Main(string[] args)
won't be triggered).
Example of an application with behavior I am attempting to replicate:
- User Opens GIMP(in Windows)
- User opens explorer and right clicks a .png file
- User selects open with GIMP
- Instead of creating a new application instance of GIMP, GIMP opens the picture in a new window within the instance of GIMP that was already opened.
In this case is GIMP employing multiple applications to accept files "opened" with file association? Or is it possible to do it with a single application "instance".
I'm having trouble with this as most of my searches tend to lead me towards file association as a Windows user (i.e. "How to associate .xls files with excel" articles).
Raymond is right of course, but if you're looking for help with the implmentation of option (1) you should probably look at What is the correct way to create a single instance application? and .NET 4 single application instance and Switch to other instance of same application
You'll notice that detecting the application is pretty easy (use a mutex). Bringing the other application and sending it a filename can be more challenging.
There are three basic solutions presented in the answers to the previously linked questions
Use
PostMessage
to send a message to 1st instance. This usesHWND_BROADCAST
which can have untended consequences.Use Microsoft.VisualBasic.ApplicationServices.ApplicationBase Of course a reference to VisualBasic gives some C# devs the willies.
Use
FindWindow
which relies on a Windows Name.
Its also worth noting that if you want the existing application to be in the front you'll need to take special care because setting the foreground can only be given away not taken. See Foreground activation permission is like love: You can't steal it, it has to be given to you and AllowSetForegroundWindow and SetForegroundWindow
There are a variety of options, but none of them come for free.
- Your program's
Main()
can detect that there is another copy already running and hand the file name off to the already-running copy by some means you determine. - Your program can register as a DDE server and request that subsequent opens be performed via DDE. This is an old-fashioned technique from the 1990's that is generally not recommended for new programs.
- You can register a custom drop target for your application, and have the drop target hand the file name to the already-running copy. This mechanism takes the form of a shell extension, and therefore is not suitable for C# due to CLR injection issues.
Given your constraints, option (1) appears to be the best option.
Microsoft created this functionality for Visual Basic .Net, and it can be used by C# too.
See the following post for a simple example in C#:
http://www.openwinforms.com/single_instance_application.html
This approach worked best for me: Enforcing Single Instance WPF Applications. Especially, its solution for passing arguments also works in notify-icon only applications.
来源:https://stackoverflow.com/questions/7798259/how-to-execute-an-event-of-already-launched-application-with-file-association