Re: [lazarus] Component to force one instance by application

2006-12-20 Thread Razvan Adrian Bogdan

Listing processes might be one way to check for instances, maybe try
to communicate with that instance to make sure it's not blocked.
There was also a simple way to check using instance handle in C wich
could be adapted to FPC but i don't know how it works in Unix world.

Razvan

On 12/17/06, Luiz Americo Pereira Camara <[EMAIL PROTECTED]> wrote:

Al Boldi wrote:
> Luiz Americo Pereira Camara wrote:
>
>> Kris Leech wrote:
>>
>>> Good stuff, did you come across any issues with simpleIPC, Ive been
>>> meaning to have a go with it for a while...
>>>
>> I had two issues with simpleipc:
>>  - in unix the TSimpleIPCServer.OnMessage event is not fired. To
>> override this, a solution is to call ReadMessage in the OnIdle event of
>> the application.
>>
>
> Try this implementation:
> 
> type
>
>   { TPeekThread }
>   TPeekThread = Class(TThread)
>   private
> FDoPeek: TNotifyEvent;
>   protected
> procedure Execute; override;
> procedure Synchronize(Method: TThreadMethod);
> Property DoPeek: TNotifyEvent read FDoPeek write FDoPeek;
>   end;
>
>   { TSimpleIPCpServer }
>   TSimpleIPCpServer = Class(TSimpleIPCServer)
>   private
> FPeek: Boolean;
> FPeekThread: TPeekThread;
> procedure PeekMethod(Sender: TObject);
> procedure SetPeek(const AValue: Boolean);
>   protected
> Procedure Activate; override;
> Procedure Deactivate; override;
>   published
> Property Peek : Boolean read FPeek write SetPeek;
>   end;
>
> implementation
>
> { TPeekThread }
> procedure TPeekThread.Execute;
> begin
>   repeat
> FDoPeek(self);
>   until Terminated;
> end;
>
> procedure TPeekThread.Synchronize(Method: TThreadMethod);
> begin
>   inherited;
> end;
>
> { TSimpleIPCpServer }
> procedure TSimpleIPCpServer.PeekMethod(Sender: TObject);
> begin
>   if PeekMessage(1000,false) then
> TPeekThread(sender).Synchronize(@ReadMessage);
> end;
>
> procedure TSimpleIPCpServer.SetPeek(const AValue: Boolean);
> begin
>   if FPeek=AValue then exit;
>   if FActive then DoError(SErrActive,[]);
>   FPeek:=AValue;
> end;
>
> procedure TSimpleIPCpServer.Activate;
> begin
>   inherited Activate;
>   if FActive and FPeek then begin
> FPeekThread:=TPeekThread.Create(true);
> FPeekThread.DoPeek:[EMAIL PROTECTED];
> FPeekThread.FreeOnTerminate:=true;
> FPeekThread.Resume;
>   end;
> end;
>
> procedure TSimpleIPCpServer.Deactivate;
> begin
>   if FActive and FPeek then begin
> FPeekThread.Terminate;
>   end;
>   inherited Deactivate;
> end;
> 
>
>
Thanks. Another solution is to use the dnotify api of the kernel.
Someone already tried dnotify with fpc?
> BTW:  Somebody know how to override a Classname, like it's possible with
> Methods.  i.e:  TComponent = Class(TComponent); override;
>
>
>>  - The other is that there's currently no easy way to diferentiate
>> between different message types. Let's say i need to send messages
>> telling i started the job, send the results of the job and than finished
>> the job. Currently there are two options: send a header in the stream
>> with a numeric variable and check it when arrive (you lose the comodity
>> of SendStringMessage) or you send a string with a string marker. I will
>> propose a change in it (and provide the patch) where we could use the
>> MessageType (user defined) to identify the message and we could still
>> use SendStringMessage .
>>
>
> Or you could use another SimpleIPC connection.
>
>
>> - another potential problem (not tested) is that in unix a file is used
>> to pass the messages. So if the program crashes the file may not be
>> deleted and would give that the server is running.
>>
>
> In unix it uses pipes.  No problem when program crashes.
>
Good to know. I don't have experience with pipes.

Luiz

_
 To unsubscribe: mail [EMAIL PROTECTED] with
"unsubscribe" as the Subject
   archives at http://www.lazarus.freepascal.org/mailarchives



_
To unsubscribe: mail [EMAIL PROTECTED] with
   "unsubscribe" as the Subject
  archives at http://www.lazarus.freepascal.org/mailarchives


Re: [lazarus] Component to force one instance by application

2006-12-17 Thread Luiz Americo Pereira Camara

Al Boldi wrote:

Luiz Americo Pereira Camara wrote:
  

Kris Leech wrote:


Good stuff, did you come across any issues with simpleIPC, Ive been
meaning to have a go with it for a while...
  

I had two issues with simpleipc:
 - in unix the TSimpleIPCServer.OnMessage event is not fired. To
override this, a solution is to call ReadMessage in the OnIdle event of
the application.



Try this implementation:

type

  { TPeekThread }
  TPeekThread = Class(TThread)
  private
FDoPeek: TNotifyEvent;
  protected
procedure Execute; override;
procedure Synchronize(Method: TThreadMethod);
Property DoPeek: TNotifyEvent read FDoPeek write FDoPeek;
  end;

  { TSimpleIPCpServer }
  TSimpleIPCpServer = Class(TSimpleIPCServer)
  private
FPeek: Boolean;
FPeekThread: TPeekThread;
procedure PeekMethod(Sender: TObject);
procedure SetPeek(const AValue: Boolean);
  protected
Procedure Activate; override;
Procedure Deactivate; override;
  published
Property Peek : Boolean read FPeek write SetPeek;
  end;

implementation

{ TPeekThread }
procedure TPeekThread.Execute;
begin
  repeat
FDoPeek(self);
  until Terminated;
end;

procedure TPeekThread.Synchronize(Method: TThreadMethod);
begin
  inherited;
end;

{ TSimpleIPCpServer }
procedure TSimpleIPCpServer.PeekMethod(Sender: TObject);
begin
  if PeekMessage(1000,false) then
TPeekThread(sender).Synchronize(@ReadMessage);
end;

procedure TSimpleIPCpServer.SetPeek(const AValue: Boolean);
begin
  if FPeek=AValue then exit;
  if FActive then DoError(SErrActive,[]);
  FPeek:=AValue;
end;

procedure TSimpleIPCpServer.Activate;
begin
  inherited Activate;
  if FActive and FPeek then begin
FPeekThread:=TPeekThread.Create(true);
FPeekThread.DoPeek:[EMAIL PROTECTED];
FPeekThread.FreeOnTerminate:=true;
FPeekThread.Resume;
  end;
end;

procedure TSimpleIPCpServer.Deactivate;
begin
  if FActive and FPeek then begin
FPeekThread.Terminate;
  end;
  inherited Deactivate;
end;


  
Thanks. Another solution is to use the dnotify api of the kernel. 
Someone already tried dnotify with fpc?
BTW:  Somebody know how to override a Classname, like it's possible with 
Methods.  i.e:  TComponent = Class(TComponent); override;


  

 - The other is that there's currently no easy way to diferentiate
between different message types. Let's say i need to send messages
telling i started the job, send the results of the job and than finished
the job. Currently there are two options: send a header in the stream
with a numeric variable and check it when arrive (you lose the comodity
of SendStringMessage) or you send a string with a string marker. I will
propose a change in it (and provide the patch) where we could use the
MessageType (user defined) to identify the message and we could still
use SendStringMessage .



Or you could use another SimpleIPC connection.

  

- another potential problem (not tested) is that in unix a file is used
to pass the messages. So if the program crashes the file may not be
deleted and would give that the server is running.



In unix it uses pipes.  No problem when program crashes.
  

Good to know. I don't have experience with pipes.

Luiz

_
To unsubscribe: mail [EMAIL PROTECTED] with
   "unsubscribe" as the Subject
  archives at http://www.lazarus.freepascal.org/mailarchives


Re: [lazarus] Component to force one instance by application

2006-12-17 Thread Al Boldi
Luiz Americo Pereira Camara wrote:
> Kris Leech wrote:
> > Good stuff, did you come across any issues with simpleIPC, Ive been
> > meaning to have a go with it for a while...
>
> I had two issues with simpleipc:
>  - in unix the TSimpleIPCServer.OnMessage event is not fired. To
> override this, a solution is to call ReadMessage in the OnIdle event of
> the application.

Try this implementation:

type

  { TPeekThread }
  TPeekThread = Class(TThread)
  private
FDoPeek: TNotifyEvent;
  protected
procedure Execute; override;
procedure Synchronize(Method: TThreadMethod);
Property DoPeek: TNotifyEvent read FDoPeek write FDoPeek;
  end;

  { TSimpleIPCpServer }
  TSimpleIPCpServer = Class(TSimpleIPCServer)
  private
FPeek: Boolean;
FPeekThread: TPeekThread;
procedure PeekMethod(Sender: TObject);
procedure SetPeek(const AValue: Boolean);
  protected
Procedure Activate; override;
Procedure Deactivate; override;
  published
Property Peek : Boolean read FPeek write SetPeek;
  end;

implementation

{ TPeekThread }
procedure TPeekThread.Execute;
begin
  repeat
FDoPeek(self);
  until Terminated;
end;

procedure TPeekThread.Synchronize(Method: TThreadMethod);
begin
  inherited;
end;

{ TSimpleIPCpServer }
procedure TSimpleIPCpServer.PeekMethod(Sender: TObject);
begin
  if PeekMessage(1000,false) then
TPeekThread(sender).Synchronize(@ReadMessage);
end;

procedure TSimpleIPCpServer.SetPeek(const AValue: Boolean);
begin
  if FPeek=AValue then exit;
  if FActive then DoError(SErrActive,[]);
  FPeek:=AValue;
end;

procedure TSimpleIPCpServer.Activate;
begin
  inherited Activate;
  if FActive and FPeek then begin
FPeekThread:=TPeekThread.Create(true);
FPeekThread.DoPeek:[EMAIL PROTECTED];
FPeekThread.FreeOnTerminate:=true;
FPeekThread.Resume;
  end;
end;

procedure TSimpleIPCpServer.Deactivate;
begin
  if FActive and FPeek then begin
FPeekThread.Terminate;
  end;
  inherited Deactivate;
end;


BTW:  Somebody know how to override a Classname, like it's possible with 
Methods.  i.e:  TComponent = Class(TComponent); override;

>  - The other is that there's currently no easy way to diferentiate
> between different message types. Let's say i need to send messages
> telling i started the job, send the results of the job and than finished
> the job. Currently there are two options: send a header in the stream
> with a numeric variable and check it when arrive (you lose the comodity
> of SendStringMessage) or you send a string with a string marker. I will
> propose a change in it (and provide the patch) where we could use the
> MessageType (user defined) to identify the message and we could still
> use SendStringMessage .

Or you could use another SimpleIPC connection.

> - another potential problem (not tested) is that in unix a file is used
> to pass the messages. So if the program crashes the file may not be
> deleted and would give that the server is running.

In unix it uses pipes.  No problem when program crashes.


Thanks!

--
Al

_
 To unsubscribe: mail [EMAIL PROTECTED] with
"unsubscribe" as the Subject
   archives at http://www.lazarus.freepascal.org/mailarchives


Re: [lazarus] Component to force one instance by application

2006-12-17 Thread Luiz Americo Pereira Camara

Kris Leech wrote:
Good stuff, did you come across any issues with simpleIPC, Ive been 
meaning to have a go with it for a while...



I had two issues with simpleipc:
- in unix the TSimpleIPCServer.OnMessage event is not fired. To 
override this, a solution is to call ReadMessage in the OnIdle event of 
the application.


- The other is that there's currently no easy way to diferentiate 
between different message types. Let's say i need to send messages 
telling i started the job, send the results of the job and than finished 
the job. Currently there are two options: send a header in the stream 
with a numeric variable and check it when arrive (you lose the comodity 
of SendStringMessage) or you send a string with a string marker. I will 
propose a change in it (and provide the patch) where we could use the 
MessageType (user defined) to identify the message and we could still 
use SendStringMessage .


- another potential problem (not tested) is that in unix a file is used 
to pass the messages. So if the program crashes the file may not be 
deleted and would give that the server is running.


Luiz

_
To unsubscribe: mail [EMAIL PROTECTED] with
   "unsubscribe" as the Subject
  archives at http://www.lazarus.freepascal.org/mailarchives


Re: [lazarus] Component to force one instance by application

2006-12-17 Thread Kris Leech
Good stuff, did you come across any issues with simpleIPC, Ive been 
meaning to have a go with it for a while...


Luiz Americo wrote:


I created a component to force one instance per application.

More info here: http://wiki.lazarus.freepascal.org/UniqueInstance

Luiz

_
To unsubscribe: mail [EMAIL PROTECTED] with
   "unsubscribe" as the Subject
  archives at http://www.lazarus.freepascal.org/mailarchives






_
To unsubscribe: mail [EMAIL PROTECTED] with
   "unsubscribe" as the Subject
  archives at http://www.lazarus.freepascal.org/mailarchives


Re: [lazarus] Component to force one instance by application

2006-12-16 Thread Luiz Americo Pereira Camara

George Birbilis wrote:

I created a component to force one instance per application.

More info here: http://wiki.lazarus.freepascal.org/UniqueInstance



Was wandering if lock files could be used instead as more cross-platform
way.
UniqueInstance is written using standard fpc/Lazarus functions and 
classes. No platform dependant hacks. All platform dependant code is 
hidden by  the FCL and the LCL. The only issue regarding diferent 
platforms is that a feature of simpleipc is missing in unix (which only 
affects the callback mechanic). Is just a question of implementing the 
missing part.

 First instance could make the lock file, the other instances could find
the lock file and just return. User could delete the lock file manually if
app fails to delete it. Problem is though:
1) need to notify running app somehow to come to front (maybe if it polls
the lock file for something being written into it or if there's some
notification for such action [I don't think there is])
  

My implementation already has such mechanism. See included examples.

2) the possibility of app remaining locked after a crash and user having to
delete a lock file manually is bad in usability terms (although I remember
[years ago] various Unix apps used to do that thing).
  
No such problems with UniqueInstance. If a app crashes other instances 
can be initiated without problem.

On Windows btw, there are better ways than TCP/IP to do this stuff, for
example custom window messages or unique window names (using a GUID/UUID
maybe to guarantee uniqueness)
  

It's not using TCP/IP. See the implementation of simpleipc.


Anyway, anyone is free to do its own implementation or even modify it: 
it's Open Source.


Luiz

_
To unsubscribe: mail [EMAIL PROTECTED] with
   "unsubscribe" as the Subject
  archives at http://www.lazarus.freepascal.org/mailarchives


Re: [lazarus] Component to force one instance by application

2006-12-16 Thread Vincent Snijders

Luiz Americo schreef:

I created a component to force one instance per application.

More info here: http://wiki.lazarus.freepascal.org/UniqueInstance



I uploaded it to 
http://sourceforge.net/project/showfiles.php?group_id=92177&package_id=215290


Vincent

_
To unsubscribe: mail [EMAIL PROTECTED] with
   "unsubscribe" as the Subject
  archives at http://www.lazarus.freepascal.org/mailarchives


RE: [lazarus] Component to force one instance by application

2006-12-16 Thread George Birbilis
> I created a component to force one instance per application.
>
> More info here: http://wiki.lazarus.freepascal.org/UniqueInstance

Was wandering if lock files could be used instead as more cross-platform
way. First instance could make the lock file, the other instances could find
the lock file and just return. User could delete the lock file manually if
app fails to delete it. Problem is though:
1) need to notify running app somehow to come to front (maybe if it polls
the lock file for something being written into it or if there's some
notification for such action [I don't think there is])
2) the possibility of app remaining locked after a crash and user having to
delete a lock file manually is bad in usability terms (although I remember
[years ago] various Unix apps used to do that thing).

On Windows btw, there are better ways than TCP/IP to do this stuff, for
example custom window messages or unique window names (using a GUID/UUID
maybe to guarantee uniqueness)


George Birbilis ([EMAIL PROTECTED])
Computer & Informatics Engineer
Microsoft MVP J# for 2004-2006
Borland "Spirit of Delphi"
3D, QuickTime, QTVR, Java, Delphi,
ActiveX, .NET components, Robotics
http://www.kagi.com/birbilis
http://birbilis.spaces.live.com




  _  

avast! Antivirus  : Outbound message clean. 


Virus Database (VPS): 0657-0, 12/12/2006
Tested on: 16/12/2006 10:12:49 ??
avast! - copyright (c) 1988-2006 ALWIL Software.



_
 To unsubscribe: mail [EMAIL PROTECTED] with
"unsubscribe" as the Subject
   archives at http://www.lazarus.freepascal.org/mailarchives