Answering follow-up question: how to show this form again by a click.
What makes this thing very different is your comment:
"I want to unhide the application by clicking on its shortcut icon which is placed on Desktop after its installation, or by running application from start menu."
Do you realize that in item on start menu is not your part of your application? The shortcut icon is the same thing. It will simply run another instance of the same application and show yet another form instead of the one which is hidden. You should not let it happen. This is called single-instance or singleton application behavior. There is no special support of this feature in .NET (probably because if can be done is different ways depending on other requirements).
Let me show only one way I use. You always have process "instance" #1. If you run it again you will always have a process "instance" #2. You can only prevent more processes to be run. You will need #2 anyway to notify #1 to show the form. Hence, whatever you can do, it always involves inter-process communications. This is how (just one way):
Remoting solution:
- Use remoting (based on pipes) to communication between instances. You only need to send a notification, no real data needed. The application should act as a listening part (call is "server" and as a connecting part (called it "client")
- When in the entry point, before running
Application
the instance should decide is it #1 or #2. Act as a client and try to connect. If connection is failed: it's #1, proceed with application. If connected, this is #2. Call a function of a remote object (see below) to show the main form. Don't do Application.Run
, exit immediately. - When the remoting "server" receives the connection, it's #1. It should show the form in question.
- For remoting, use
IpcClientChannel
and IpcServerChannel
. A channel requires a channel name. You can use any string, but how to make it unique? You can include the unique location of your application: System.Reflection.Assembly.GetEntryAssembly().Location
. It will return the unique location (assuming application installed only in a single location) of the main module of the entry assembly (usually this is your .exe
file). - For remoting you will need a server object and some (rudimentary) interface, call it
IShowMainForm
,and call the server object class ShowMainForm
. So the server object will be class ShowMainForm : System.MarshalByRefObject, IShowMainForm {}
. In this class, it is important to implement (override) InitializeLifetimeService
. Do it in the simplest way: public override object InitializeLifetimeService() { return null; }
. If you forget it, the server will be time-outed. - In the interface
IShowMainForm
you need just one function void Show
. This function is called on the remote object by the process #2 (see above) and implemented by the application's ShowMainForm
. It should show your main form and also call it's method Activate
.
In the code, this is easy enough, will be few tens of lines, but you need to implement rudimentary remoting. There are no simple ways. The idea is very easy to implement, but .NET code behind remoting is quite sophisticated.
Alternative solutions:
Another option (may be easy, I did not try) is self-hosting WCF. One simple solution is to list all processes, recognize #1 by its location (see my advice about channel name based on unique location, same thing here). The problem is: who to send notification to show main form? I don't know, so what, remoting again? So, this would not add much.
There are more simple inter-process communication (people ofter use system-wide Mutex or event wait handle), but the problem is how to trigger the event to show the main form (some solutions of single-instance application do not provide it).
You can always ignore the problem of second instance completely and deal with the consequences (customer support will answer: "you're not supposed to run it again"). If you use simpler alternative solution without sending notification to #1, you can simply terminate #2 every time it detects #1. This can be more simple. In this case, you will need to show a form by clicking on something else. This "something else" can be a tray icon. Implement a tray icon application (use the reference I gave you in my other answer to start with). This tray icon application will also show the form on click on the system tray. You should show the form in all cases, regardless the status. This would be exact same form which is now your main form.
I would implement both tray icon application and the remoting solution for inter-process communication. Only in this case you will have the features adequate to the application purpose.
The application you're doing is not going to be very simple. So, I would share what I did... See below.
Very alternative solution :-)
I have done a good downloading application for myself. This is a console application based on command line. It can work with the partially downloaded files (complete them). I even posted the full source code in one of my answers. For the tasks like that I hate any UI solution, no matter what is does. It takes so much time and hassle not only to write one, but even to simply use it: click here, click there, copy-paste URL... boring and cumbersome. With good command line I can take existing list of URLs, combine them in a simple batch file and run, get the log in the other file. Easy and simple.
—SA