BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Only One Instance.
Goto page 1, 2  Next
 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> comp.lang.pascal.delphi.misc
View previous topic :: View next topic  
Author Message
John Dammeyer
Guest





PostPosted: Wed Jan 14, 2004 5:07 pm    Post subject: Only One Instance. Reply with quote



Hi All,

My application needs to run on program startup. I've had it working
well with an entry into the registry but during development I made a
few errors and ended up with two app.exe entries in the registry. I
can't ever have more than one instance running due to hardware
accesses.

Remoing the multiple entries was not a big problem to handle with
regedit.exe but in C I can check hPrevInstance to see if there is
already something running. e.g.

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR
lpCmdLine,


And then exit out if hPrevInstance was non zero.

How do I do this in Delphi 5? I've searched the Forms and System
files but can't find anything specific.

Thanks,

John

Back to top
Dave
Guest





PostPosted: Wed Jan 14, 2004 5:45 pm    Post subject: Re: Only One Instance. Reply with quote



"John Dammeyer" <johnd (AT) STRIP (DOT) autoartisans.com> wrote

Quote:
Hi All,

My application needs to run on program startup. I've had it working
well with an entry into the registry but during development I made a
few errors and ended up with two app.exe entries in the registry. I
can't ever have more than one instance running due to hardware
accesses.

Remoing the multiple entries was not a big problem to handle with
regedit.exe but in C I can check hPrevInstance to see if there is
already something running. e.g.

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR
lpCmdLine,


And then exit out if hPrevInstance was non zero.

How do I do this in Delphi 5? I've searched the Forms and System
files but can't find anything specific.

This is what I use. Not my code...I think I got it from someone in
this group quite a while back, but it works like a charm:

//Prevent multiple instances of the program from running
StrPCopy(MutexName, 'anyname');
Mutex := OpenMutex(MUTEX_ALL_ACCESS, False, MutexName);
If Mutex <> 0 then begin
Exit;
end;
Mutex := CreateMutex(nil , True, MutexName);
ReleaseMutex(Mutex);

- Dave



Back to top
Rob Kennedy
Guest





PostPosted: Wed Jan 14, 2004 6:17 pm    Post subject: Re: Only One Instance. Reply with quote



John Dammeyer wrote:
Quote:
Remoing the multiple entries was not a big problem to handle with
regedit.exe but in C I can check hPrevInstance to see if there is
already something running. e.g.

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR
lpCmdLine,

And then exit out if hPrevInstance was non zero.

You can? As I understand it, as of 1995, that parameter will always be
zero. Win32 doesn't have instance handles anymore.

You can use the HPrevInst variable in Delphi, which is initialized the
same way WinMain's parameter is. It won't be of any use, though.

Quote:
How do I do this in Delphi 5? I've searched the Forms and System
files but can't find anything specific.

Have you searched the newsgroups?

When using CreateMutex, please read the documentation carefully
regarding choosing a name. The naming rules vary by OS version, and some
names have a wider scope than others.

--
Rob

Back to top
Maarten Wiltink
Guest





PostPosted: Wed Jan 14, 2004 7:19 pm    Post subject: Re: Only One Instance. Reply with quote

"John Dammeyer" <johnd (AT) STRIP (DOT) autoartisans.com> wrote

Quote:
Hi All,

My application needs to run on program startup. I've had it working
well with an entry into the registry but during development I made a
few errors and ended up with two app.exe entries in the registry. I
can't ever have more than one instance running due to hardware
accesses.

Remoing the multiple entries was not a big problem to handle with
regedit.exe but in C I can check hPrevInstance to see if there is
already something running. e.g.

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR
lpCmdLine,


And then exit out if hPrevInstance was non zero.

How do I do this in Delphi 5? I've searched the Forms and System
files but can't find anything specific.

http://www.bancoems.com/CompLangPascalDelphiMisc-MiniFAQ.htm

Question two.

Groetjes,
Maarten Wiltink



Back to top
Leonardo Cardoso Monteiro
Guest





PostPosted: Wed Jan 14, 2004 8:22 pm    Post subject: Re: Only One Instance. Reply with quote

"John Dammeyer" <johnd (AT) STRIP (DOT) autoartisans.com> wrote

Quote:
Hi All,

My application needs to run on program startup. I've had it working
well with an entry into the registry but during development I made a
few errors and ended up with two app.exe entries in the registry. I
can't ever have more than one instance running due to hardware
accesses.

Remoing the multiple entries was not a big problem to handle with
regedit.exe but in C I can check hPrevInstance to see if there is
already something running. e.g.

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR
lpCmdLine,


And then exit out if hPrevInstance was non zero.

How do I do this in Delphi 5? I've searched the Forms and System
files but can't find anything specific.

Thanks,

John



From MS documentation:

hPrevInstance
[in] Handle to the previous instance of the application. This parameter is
always NULL. If you need to detect whether another instance already exists,
create a uniquely named mutex using the CreateMutex function. CreateMutex
will succeed even if the mutex already exists, but the function will return
ERROR_ALREADY_EXISTS. This indicates that another instance of your
application exists, because it created the mutex first.

Leonardo




Back to top
Rob Kennedy
Guest





PostPosted: Wed Jan 14, 2004 9:09 pm    Post subject: Re: Only One Instance. Reply with quote

Jamie wrote:
Quote:
i always found that if you can only have one instance of the app then
you should Special Name the Main Form Class to something that should
never exist, use the FINDWIndow in the Main Source before The
TAPplication.initiate gets executed..

Or, you could simply create a mutex. Advantages:

1. The name of the mutex has no effect on anything else in your program,
so you can continue to name your objects however you want.

2. The mutex name is more likely to be unique within the system. You can
even use a GUID.

3. Mutex creation is atomic. It is impossible for two processes to
create like-named mutexes without knowing it. Creating a window, on the
other hand, is not atomic. If process A and process B are started
simultaneously, they might both call FindWindow before either one has
created the window that the other process is looking for.

Quote:
if you find the CLASS then you should use the SENDMESSAGE to that
handle that you have receieved with a special user message that you have
your app responed to .. if all of this falls into play then you can be
as sured that you have a copy of your app running.

But there is no guarantee that any of that will fall into place.

When your main form is open in the IDE, it has the same class name and
title as the form your program creates. FindWindow might find that
window, which makes testing and debugging inconvenient. FindWindow is an
attractive function because it's easy to use and it's easy for novices
to understand. But it's simply not the right tool for the job.

Quote:
there the methods that others use like CreateMutex etc.. but i found
that if the SENDMESSAGE works your app can return back aditional info
that you may want also to insure its your app and not just some fluke
that there is another app on the desktop running that way.,..

Using a mutex does not preclude usage of other techniques for
transferring control to the previous instance. However, a mutex is a
guaranteed method of detecting multiple instances. FindWindow offers
absolutely no guarantees.

Besides, if the window you find doesn't return the value you were
expecting, then you've determined that you didn't find the right window.
But now what? You still can't conclude that no other instances of your
program are running. FindWindow only returns one window, and it always
returns the first one it finds.

If you want to communicate with the existing instance of a program, then
you can use a mailslot instead of a mutex. Like mutex names, mailslot
names are unique on a system, so you can use CreateMailslot just as you
would use CreateMutex. Mailslots also allow you to send information to
the first instance, so the first instance can receive subsequent
instances' command-line parameters.

--
Rob

Back to top
John Dammeyer
Guest





PostPosted: Wed Jan 14, 2004 10:15 pm    Post subject: Re: Only One Instance. Reply with quote

"Leonardo Cardoso Monteiro" <cardoso (AT) iis (DOT) com.br> wrote:

Hi,

Thanks. Shows how dated I am on Windows Programming for some things.
My target is a WIN98SE system. I'll check out the MUTEX stuff.

Thanks,

John


Quote:
From MS documentation:

hPrevInstance
[in] Handle to the previous instance of the application. This parameter is
always NULL. If you need to detect whether another instance already exists,
create a uniquely named mutex using the CreateMutex function. CreateMutex
will succeed even if the mutex already exists, but the function will return
ERROR_ALREADY_EXISTS. This indicates that another instance of your
application exists, because it created the mutex first.

Leonardo






Back to top
John Dammeyer
Guest





PostPosted: Wed Jan 14, 2004 10:32 pm    Post subject: Re: Only One Instance. Reply with quote

dank ja wel,

This worked perfect. With a running instance I can click on the .exe
file over and over again and it never starts a second one.

John


"Maarten Wiltink" <maarten (AT) kittensandcats (DOT) net> wrote:

Quote:
"John Dammeyer" <johnd (AT) STRIP (DOT) autoartisans.com> wrote in message
news:40057530.3496597 (AT) news (DOT) islandnet.com...
Hi All,

My application needs to run on program startup.

<snip>
Quote:

How do I do this in Delphi 5? I've searched the Forms and System
files but can't find anything specific.

http://www.bancoems.com/CompLangPascalDelphiMisc-MiniFAQ.htm

Question two.

Groetjes,
Maarten Wiltink




Back to top
Jamie
Guest





PostPosted: Wed Jan 14, 2004 11:08 pm    Post subject: Re: Only One Instance. Reply with quote

i always found that if you can only have one instance of the app then
you should Special Name the Main Form Class to something that should
never exist, use the FINDWIndow in the Main Source before The
TAPplication.initiate gets executed..
if you find the CLASS then you should use the SENDMESSAGE to that
handle that you have receieved with a special user message that you have
your app responed to .. if all of this falls into play then you can be
as sured that you have a copy of your app running.
there the methods that others use like CreateMutex etc.. but i found
that if the SENDMESSAGE works your app can return back aditional info
that you may want also to insure its your app and not just some fluke
that there is another app on the desktop running that way.,..


John Dammeyer wrote:

Quote:
Hi All,

My application needs to run on program startup. I've had it working
well with an entry into the registry but during development I made a
few errors and ended up with two app.exe entries in the registry. I
can't ever have more than one instance running due to hardware
accesses.

Remoing the multiple entries was not a big problem to handle with
regedit.exe but in C I can check hPrevInstance to see if there is
already something running. e.g.

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR
lpCmdLine,


And then exit out if hPrevInstance was non zero.

How do I do this in Delphi 5? I've searched the Forms and System
files but can't find anything specific.

Thanks,

John



Back to top
J French
Guest





PostPosted: Thu Jan 15, 2004 8:24 am    Post subject: Re: Only One Instance. Reply with quote

On Wed, 14 Jan 2004 17:07:34 GMT, [email]johnd (AT) STRIP (DOT) autoartisans.com[/email] (John
Dammeyer) wrote:

Quote:
Hi All,

My application needs to run on program startup. I've had it working
well with an entry into the registry but during development I made a
few errors and ended up with two app.exe entries in the registry. I
can't ever have more than one instance running due to hardware
accesses.

<snip>

Apart from Mutexes, RegisterWindowsMessage is handy for this sort of
thing

Back to top
Jamie
Guest





PostPosted: Thu Jan 15, 2004 10:08 am    Post subject: Re: Only One Instance. Reply with quote

well what ever, i have used AToms, Mutexes, MemoryFile and FindWIndow
with post backs. i can tell you that for me using custom name Main
Window Classes per APP not the default "TFORM1" that every one uses with
post back helps me grately. because it also is able to return back to
the secondary app the handle info of the original app along with what
ever else i need for it at the time.
this way i can pop the original to the front and then exist the secondary
etc..
i am sure that your way works well for what you do, i have extra
requirements on some of the code i write.
I also had to use EnumWindows, get the Handle, use PostBack function
to get the start up times and other initiated info per instant. so that
the current instant coming up would be inline with the others..
so what ever., i guess what ever way works for it is what you use..


Rob Kennedy wrote:
Quote:
Jamie wrote:

i always found that if you can only have one instance of the app then
you should Special Name the Main Form Class to something that should
never exist, use the FINDWIndow in the Main Source before The
TAPplication.initiate gets executed..


Or, you could simply create a mutex. Advantages:

1. The name of the mutex has no effect on anything else in your program,
so you can continue to name your objects however you want.

2. The mutex name is more likely to be unique within the system. You can
even use a GUID.

3. Mutex creation is atomic. It is impossible for two processes to
create like-named mutexes without knowing it. Creating a window, on the
other hand, is not atomic. If process A and process B are started
simultaneously, they might both call FindWindow before either one has
created the window that the other process is looking for.

if you find the CLASS then you should use the SENDMESSAGE to that
handle that you have receieved with a special user message that you
have your app responed to .. if all of this falls into play then you
can be
as sured that you have a copy of your app running.


But there is no guarantee that any of that will fall into place.

When your main form is open in the IDE, it has the same class name and
title as the form your program creates. FindWindow might find that
window, which makes testing and debugging inconvenient. FindWindow is an
attractive function because it's easy to use and it's easy for novices
to understand. But it's simply not the right tool for the job.

there the methods that others use like CreateMutex etc.. but i found
that if the SENDMESSAGE works your app can return back aditional info
that you may want also to insure its your app and not just some fluke
that there is another app on the desktop running that way.,..


Using a mutex does not preclude usage of other techniques for
transferring control to the previous instance. However, a mutex is a
guaranteed method of detecting multiple instances. FindWindow offers
absolutely no guarantees.

Besides, if the window you find doesn't return the value you were
expecting, then you've determined that you didn't find the right window.
But now what? You still can't conclude that no other instances of your
program are running. FindWindow only returns one window, and it always
returns the first one it finds.

If you want to communicate with the existing instance of a program, then
you can use a mailslot instead of a mutex. Like mutex names, mailslot
names are unique on a system, so you can use CreateMailslot just as you
would use CreateMutex. Mailslots also allow you to send information to
the first instance, so the first instance can receive subsequent
instances' command-line parameters.



Back to top
Bruce Roberts
Guest





PostPosted: Thu Jan 15, 2004 3:29 pm    Post subject: Re: Only One Instance. Reply with quote


"John Dammeyer" <johnd (AT) STRIP (DOT) autoartisans.com> wrote


Quote:
This worked perfect. With a running instance I can click on the .exe
file over and over again and it never starts a second one.

Actually a second instance is started every time. It just exits before doing
anything significant.



Back to top
Maarten Wiltink
Guest





PostPosted: Thu Jan 15, 2004 7:46 pm    Post subject: Re: Only One Instance. Reply with quote

"Bruce Roberts" <ber (AT) bounceitattcanada (DOT) xnet> wrote

Quote:
"John Dammeyer" <johnd (AT) STRIP (DOT) autoartisans.com> wrote in message
news:4005c2e7.23391004 (AT) news (DOT) islandnet.com...

<miniFAQ>

Quote:
This worked perfect. With a running instance I can click on the .exe
file over and over again and it never starts a second one.

Actually a second instance is started every time. It just exits before
doing anything significant.

If it could insignificantly bring the previous instance to the foreground,
I would consider that significant and quite useful. I don't know if you
can still do that, though. Didn't the behaviour change some time ago to
merely flashing the taskbar button rather than grabbing the focus?

Groetjes,
Maarten Wiltink



Back to top
Ian Robinson
Guest





PostPosted: Fri Jan 16, 2004 10:53 am    Post subject: Re: Only One Instance. Reply with quote

I use this...


function DoIExist: Boolean;
var
hSem: THandle;
begin
//Create a Semaphore in memory - If this is the first instance, then
//it should be 0.
hSem := CreateSemaphore (nil, 0, 1, PChar ('Nainosnibor'));
Result := GetLastError = ERROR_ALREADY_EXISTS;
if Result then
CloseHandle (hSem);
end;




In message <40057530.3496597 (AT) news (DOT) islandnet.com>, John Dammeyer
<johnd (AT) STRIP (DOT) autoartisans.com> said
Quote:
Hi All,

My application needs to run on program startup. I've had it working
well with an entry into the registry but during development I made a
few errors and ended up with two app.exe entries in the registry. I
can't ever have more than one instance running due to hardware
accesses.

Remoing the multiple entries was not a big problem to handle with
regedit.exe but in C I can check hPrevInstance to see if there is
already something running. e.g.

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR
lpCmdLine,


And then exit out if hPrevInstance was non zero.

How do I do this in Delphi 5? I've searched the Forms and System
files but can't find anything specific.

Thanks,

John



--
Best regards
Ian Robinson FOREST SOFTWARE
+44(0)1594 564457 (Office)
+44(0)7718 806 006 (UK Mobile)
+34 653 209 592 (Overseas Mobile)
+44(0)1594 564038 (Out of hours support)

Back to top
Jeremy Collins
Guest





PostPosted: Fri Jan 16, 2004 12:02 pm    Post subject: Re: Only One Instance. Reply with quote

Ian Robinson wrote:

Quote:
I use this...

hSem := CreateSemaphore (nil, 0, 1, PChar ('Nainosnibor'));

Any particular design reasons for creating a semaphore, rather
than a mutex? Just curious; most people go for the simpler call
to CreateMutex.


--
jc

Remove the -not from email

Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> comp.lang.pascal.delphi.misc All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.