User forums > General (but related to Code::Blocks)

Multiple Instances

(1/5) > >>

thomas:
Code::Blocks used to have the multiple instances issue (you could accidentially open the same files in two instances and mess up terribly, especially when double-clicking something in Explorer). This behaviour has been adressed in RC1.

However, it is still not practical. Either you get the same behaviour as before (several copies) or you get a messagebox which disrupts your workflow, but you do not get the action you asked for.

So, during the last weeks, I have sporadically been thinking about this problem. Unluckily, it is not as easy as "well, tell the other instance..." because there is no such thing, at least not in an easy way, and not cross-platform.

wxWidgets does have some IPC support, but honestly, I am unable to understand both the API and the documentation that comes with it. It only seems to work on Windows if you have DDE running, too (which happens to be disabled on my machine).  Also, from various sources on the web, I gather it does not work the same everywhere. In one word: it kind of sucks.
There are proposed solutions of using named pipes or TCP sockets and whatever complicated stuff instead. Named pipes.... uh huh, who wants to implement that on several platforms? Step forward please.
TCP connections... great plan, but on my machine, like on many others too, ZoneAlarm pops up an alert each time a new application opens a TCP connection. This may lead to a quite negative first impression ("What the hell are they doing? Network == Spyware") on a new user.

So... in the end, I came up with the idea that using signal handlers and OS messages (with two separate codepaths) is maybe not so complicated and not so bad at all. It is only a rough idea yet, but well, look at it and give your ideas/comments :)

(I) Change MainFrame::MainFrame to pass CODEBLOCKS_WINDOW_ID to wxFrame rather than -1

(II) If another instance is found:
1. Create a temporary file inside WELL_KNOWN_FOLDER

2. Write the commandline into that file

3. a) on every OS except Windows:
    - send SIGHUP to the other process
    - SIGHUP is caught by the other process and ReadAlienCommandline() is called

3. b) on Windows:
 - use FindWindow(CODEBLOCKS_WINDOW_ID, -1) and PostMessage()
   to post SOME_MESSAGE to the first code::blocks window found
 - override virtual wxApp::ProcessMessage(), and call ReadAlienCommandline() if SOME_MESSAGE arrives

4. ReadAlienCommandline()
 - opens *any* present file in WELL_KNOWN_FOLDER
 - reads them in, parses the commandline, and does something in response (open a source file etc.)
 - deletes the tempfiles

Since we don't open a dozen of instances per second (one every couple of minutes is more like it), the overhead of writing and reading to/from a file should be nil.

grv575:

--- Quote from: thomas on September 07, 2005, 12:21:01 pm ---
(II) If another instance is found:
1. Create a temporary file inside WELL_KNOWN_FOLDER

...

4. ReadAlienCommandline()
 - opens *any* present file in WELL_KNOWN_FOLDER
 - reads them in, parses the commandline, and does something in response (open a source file etc.)
 - deletes the tempfiles

--- End quote ---

Never, ever do that.   If the application crashes and leaves temp files behind, it is an absolute nightmare to deal with.  I had to maintain a socket application that did exactly this (temp files in the hopes of a custom cross-platform locking mechanism)  and it was insane to debug and get all states to work correctly.   Ended up just writing a simple app from scratch which used atomic IPC.  Much better to use the OS locking mechanisms or maybe look into the wxWidgets wrappers.

rickg22:
I thought there was the appsomethingserver class so processes could communicate with each other... but shouldn't it be easy just not save the config/workspace if there was another instance running?

grv575:
Well most multiinstance programs just ignore the issue and let each one modify configuration settings, etc.  Look at netscape.  If you have many netscape processes, they can each change settings and when they hit apply or ok, the settings are updated to the last one to hit apply or ok.

Windows explorer does this as well (you can save windows position, size when it is closed.  the last window closed for a specific folder is the one that gets the final write.  so it's position and size are the one that are restored when you open exporer again to that folder).

Edit: I don't quite get it though.  I have 2 instances of CB open.  I double click a .cbp file (with DDE server off) and it launches a new, 3rd CB.  So what's the gotcha?

rickg22:
Hmmm that's what DDE is for. So it won't open a new C::B instance each time.

Navigation

[0] Message Index

[#] Next page

Go to full version