Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2013-04

File Association and opening with already running app

13 messages · 7 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Graeme Geldenhuys

Hi,

I'm posting it here, but it is not a Lazarus question, but a general GUI app (created with FPC) question.

Example of what I want to achieve. Say I have gEdit (Gnome editor) open and have a file loaded. Now if I am in a console and type 'gedit someotherfile.txt' [or double click a text file in Nautilus], it doesn't start a new instance of gedit, the existing instance opens the new file
- gedit supports multiple opened files in a tabbed view.

How do they accomplish this? I would like to implement something like that for fpGUI, and it must work under all fpGUI supported "desktop" platforms.

I know under Windows you can check if an instance of an application is already running, and stop your current instance. Still not sure how to transfer the "open a new file" action to that existing instance.

As for Linux, FreeBSD etc, I have no clue how to do it. For those not in the know, fpGUI is based directly on GDI or XLib (not Qt, GTK etc).

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email

Mark Morgan Lloyd
to Graeme Geldenhuys: I'm posting it here, but it is not a Lazarus question, but a general GUI app (created…
Graeme Geldenhuys wrote 16 lines
Example of what I want to achieve. Say I have gEdit (Gnome editor) open and have a file loaded. Now if I am in a console and type 'gedit someotherfile.txt' [or double click a text file in Nautilus], it doesn't start a new instance of gedit, the existing instance opens the new file - gedit supports multiple opened files in a tabbed view. How do they accomplish this? I would like to implement something like that for fpGUI, and it must work under all fpGUI supported "desktop" platforms. I know under Windows you can check if an instance of an application is already running, and stop your current instance. Still not sure how to transfer the "open a new file" action to that existing instance. As for Linux, FreeBSD etc, I have no clue how to do it. For those not in the know, fpGUI is based directly on GDI or XLib (not Qt, GTK etc).

I've done it on Linux by explicitly setting up a unix-domain socket and writing a command to that if the process that created it is still running, Mozilla (Firefox etc.) does similar via an ORB. There's lots of "gotchas" in here: in some cases you want to fork a distinct program instance and having to do so via a separate named profile can be inconvenient.

So far I've had no success porting that to Windows using named pipes, I suggest you look at how lhelp works (and confer with Reinier et al.).

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Graeme Geldenhuys
to Mark Morgan Lloyd
Mark Morgan Lloyd wrote
So far I've had no success porting that to Windows using named pipes,

Ah, thanks for the idea. SimpleIPC should be able to do the trick - similar to how apps communicate to a DebugServer (using dbugintf and SimpleIPC units).

First instance will search for a known IPC server, if none exist, start the Simple IPC server. Second instance will first see if a existing IPC server exists, and if so, send the open command to it, then quit.

That should work in a cross-platform way too.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email

Graeme Geldenhuys
to Luca Olivetti: Al 04/04/13 11:08, En/na Graeme Geldenhuys ha escrit: Look at…

Hi Luca,

Thanks for the link.

Luca Olivetti wrote

"Just drop in the main form of a LCL application (it's on the System tab, look for a red full-circle with the digit "1" in the middle)."

I'm running Lazarus 1.1 r40661 FPC 2.6.3 x86_64-freebsd-gtk2, and I don't have such a component. No matter, from the description on the wiki page, it sounds similar to my other response about using SimpleIPC.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email

Mark Morgan Lloyd
to Graeme Geldenhuys: Ah, thanks for the idea. SimpleIPC should be able to do the trick - similar to how apps…
Graeme Geldenhuys wrote 10 lines
On 2013-04-04 10:45, Mark Morgan Lloyd wrote: > So far I've had no success porting that to Windows using named pipes, Ah, thanks for the idea. SimpleIPC should be able to do the trick - similar to how apps communicate to a DebugServer (using dbugintf and SimpleIPC units). First instance will search for a known IPC server, if none exist, start the Simple IPC server. Second instance will first see if a existing IPC server exists, and if so, send the open command to it, then quit.

Yes, I agree. But my preference is to put the socket/pipe in the user's home directory (i.e. rather than /tmp which is where it's usually put), to name it including the PID to make it easily trackable, and to use some combination of the original project name, the final executable name (and possibly something from a .ini file) so that it's possible to handle multiple instances.

I suggest also adding status commands etc., i.e. so that you can query whether a server's running, what its build is and so on. The way I did it wasn't very good for that: it really needs bidirectional communications (e.g. so that you can get the running copy's version rather than just a version number from the binary you've just executed) which isn't something I designed in.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Dennis
to Mark Morgan Lloyd

In windows, you can create Mutex. That's how I ensure no other instance of the same program is running.

YourIDString is a string that you use to uniquely id your program instance .

   if OpenMutex(MUTEX_ALL_ACCESS, False, PChar(YourIDString)) = 0 then begin
     // First one - the mutex didn't exist, so create it.
     Result := CreateMutex(nil, False, PChar(YourIDString));
     MutexList.Add(pointer(Result));
   end else begin
     raise Exception.Create('The same program has been running already');
   end;

Make sure your free all mutex in the finalization of your unit or program

procedure FreeAllMutexes;
var
   M       : THandle;
   i       : integer;
begin
   for i := 0 to MutexList.Count - 1 do begin
     M := THandle(MutexList[i]);
     if M  0 then begin
       if not CloseHandle(M) then
         raise Exception.Create('Failed to release mutex:' + IntToStr(M));
       MutexList[i] := nil;
     end;
   end;
end;
Mark Morgan Lloyd wrote 26 lines
Graeme Geldenhuys wrote: > On 2013-04-04 10:45, Mark Morgan Lloyd wrote: >> So far I've had no success porting that to Windows using named pipes, > > Ah, thanks for the idea. SimpleIPC should be able to do the trick - > similar to how apps communicate to a DebugServer (using dbugintf and > SimpleIPC units). > > First instance will search for a known IPC server, if none exist, start > the Simple IPC server. Second instance will first see if a existing IPC > server exists, and if so, send the open command to it, then quit. Yes, I agree. But my preference is to put the socket/pipe in the user's home directory (i.e. rather than /tmp which is where it's usually put), to name it including the PID to make it easily trackable, and to use some combination of the original project name, the final executable name (and possibly something from a .ini file) so that it's possible to handle multiple instances. I suggest also adding status commands etc., i.e. so that you can query whether a server's running, what its build is and so on. The way I did it wasn't very good for that: it really needs bidirectional communications (e.g. so that you can get the running copy's version rather than just a version number from the binary you've just executed) which isn't something I designed in.

Reply by email

waldo kitty
to Graeme Geldenhuys: I'm posting it here, but it is not a Lazarus question, but a general GUI app (created…
Graeme Geldenhuys wrote 9 lines
Example of what I want to achieve. Say I have gEdit (Gnome editor) open and have a file loaded. Now if I am in a console and type 'gedit someotherfile.txt' [or double click a text file in Nautilus], it doesn't start a new instance of gedit, the existing instance opens the new file - gedit supports multiple opened files in a tabbed view. How do they accomplish this? I would like to implement something like that for fpGUI, and it must work under all fpGUI supported "desktop" platforms.

notepad++ does this also... or you can configure it to open multiple times... i don't know if you can pick out how notepad++ is doing this from their code... i don't know...

http://sourceforge.net/projects/notepad-plus/

this is one case where i like the single process with multiple tabs but i can't stand it in my browser(s)...

Reply by email

Graeme Geldenhuys
to waldo kitty
waldo kitty wrote
this is one case where i like the single process with multiple tabs but i can't stand it in my browser(s)...

I have a few apps that need the functionality, but in most cases it will be user configurable. Everybody has different preferences, and I'll cater for that.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email

Graeme Geldenhuys
to Dennis: In windows, you can create Mutex. That's how I ensure no other instance of the same…
Dennis wrote
In windows, you can create Mutex. That's how I ensure no other instance of the same program is running.

Yes I know that bit, and that is what I did for my old VB6 and Delphi 5 projects. The question here was not only about a "single instance" application, but also how to pass information to the first instance (eg: please open this new file in a tab) before the second instance terminates.

Using SimpleIPC should do the trick nicely.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email

Zaher Dirkey
to Graeme Geldenhuys: I'm posting it here, but it is not a Lazarus question, but a general GUI app (created…

Please tell us you success story when you done

For me i am using SimpleIPC
https://github.com/parmaja/miniedit/blob/master/source/gui/mne.lpr

look at AnotherInstance and MainUnit.pas

Works good in Windows but not tested in Linux.

Graeme Geldenhuys wrote 35 lines
Hi, I'm posting it here, but it is not a Lazarus question, but a general GUI app (created with FPC) question. Example of what I want to achieve. Say I have gEdit (Gnome editor) open and have a file loaded. Now if I am in a console and type 'gedit someotherfile.txt' [or double click a text file in Nautilus], it doesn't start a new instance of gedit, the existing instance opens the new file - gedit supports multiple opened files in a tabbed view. How do they accomplish this? I would like to implement something like that for fpGUI, and it must work under all fpGUI supported "desktop" platforms. I know under Windows you can check if an instance of an application is already running, and stop your current instance. Still not sure how to transfer the "open a new file" action to that existing instance. As for Linux, FreeBSD etc, I have no clue how to do it. For those not in the know, fpGUI is based directly on GDI or XLib (not Qt, GTK etc). Regards, - Graeme - -- fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
I am using last revision of Lazarus, FPC 2.6 on Windows XP SP3 Best Regards Zaher Dirkey

Reply by email

Graeme Geldenhuys
to Zaher Dirkey
Zaher Dirkey wrote
Please tell us you success story when you done

All done and it works perfectly under Linux, FreeBSD and Windows. All in about 30 lines of code, which includes the client and server parts. :)

SimpleIPCServer just works a bit weird though - but that's probably because I haven't used IPC much in any of my work. Either way, a quick glance at the docs and my dbugsrv implementation and I was all sorted.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email

luiz americo pereira camara
to Graeme Geldenhuys: Yes I know that bit, and that is what I did for my old VB6 and Delphi 5 projects. The…

2013/4/5 Graeme Geldenhuys :

Show quoted text 9 lines
On 2013-04-04 16:34, Dennis wrote: > In windows, you can create Mutex. That's how I ensure no other instance > of the same program is running. Yes I know that bit, and that is what I did for my old VB6 and Delphi 5 projects. The question here was not only about a "single instance" application, but also how to pass information to the first instance (eg: please open this new file in a tab) before the second instance terminates.

The uniqueinstance componente does all this

Luiz

Reply by email