Showing posts with label uniqueinstance. Show all posts
Showing posts with label uniqueinstance. Show all posts

Saturday, December 16, 2006

Only one instance

Usually each time you launch an application a new instance is created, but sometimes is not desired to have more than one instance running. There was no way to force only one instance using Lazarus/fpc and was some discussion in the maillist the best way of implementing it (using mutex, file locking etc). I had a different idea: how about to use simpleipc, a IPC mechanism which comes in fpc?

So i started to implement such component based in simpleipc. First i searched how the Delphi programmers resolved this problem. I found two open source components TRunOnce and TInstanceControl. Both uses a file mapping technic which is win32 centric, so without use for me and i already had another idea. But i learned with them that the best place to do the implemantation is inside the Loaded procedure which is called just after the components are streamed and before the form is show.

The algorithm is pretty simple: a client (TSimpleIPCClient) checks is there's a corresponding server (TSimpleIPCServer) running, if so (a instance is already running) notify the server (the running instance) and terminate the app, otherwise it means that is the first instance so init a server and let the program go.

The next step was a little more difficult: how to pass the command line arguments to the second instance. I had 3 options:
  • Pass the cmdline as is and let the receiver (server) parse it. Not good since the parsing of the command line is not so simple and probably platform dependent
  • Pass each argument (ParamStr(x)) separately. It was considered but, in the server side, i needed a way to tell that the argument passing was starting (to set the length of the array), than pass the parameters itself and finally notify that the arguments finished (to fire the event). I could do that passing special chars as markers or with numerical values in the beginning of the stream. Definitely an overkill.
  • Create an easily parsable string with the parameters in the client side and then send once. The chosen one.
To the tests. Aside from a bug of the style for x:=1 to y do; everything worked fine. Only one annoyance: the form was being show in a few instants before it was killed. So, looking at TApplication.Run i found a ShowMainForm property and voila: no flashing form.

The results can be found here

Delphi is far away from Lazarus/fpc, no doubt, but this is an example that some problems can be resolved cleaner and easier with the open source solution.

PS: more difficult than write the component is creating a icon for it. And the result... LOL