Thread View: comp.os.ms-windows.programmer.misc
18 messages
18 total messages
Started by Alois Buecherl
Mon, 03 Feb 1997 00:00
How to avoid multiple instances of a program in NT and 95?
Author: Alois Buecherl
Date: Mon, 03 Feb 1997 00:00
Date: Mon, 03 Feb 1997 00:00
15 lines
1417 bytes
1417 bytes
Hello, I've been striving for so long now to find a SAVE way to start only one instance of my C++ program under Windows NT and 95. As you might recall, this used to be that easy in Windows 3.1 using the prevInstance variable. Now this option is gone. I've tried using a semaphore that get's locked when the programm's up. But it still can happen, that the program starts up more than once when multiple prgram spawns occur very rapidly. The program then did not get enough startup-time to create and lock the semaphore. Is there ANY solution to this problem? Any hint into a possibly right direction would be greatly appreciated! Alois
Re: How to avoid multiple instances of a program in NT and 95?
Author: Richard Baldwin
Date: Mon, 03 Feb 1997 00:00
Date: Mon, 03 Feb 1997 00:00
100 lines
4300 bytes
4300 bytes
In article <5d4eeb$n6u$1@euler.space.net>, Alois Buecherl
<Alois.Buecherl@terraSat.de> writes
>Hello,
>I've been striving for so long now to find a SAVE way to start only one
>instance of my C++ program under Windows NT and 95. As you might recall, this
>used to be that easy in Windows 3.1 using the prevInstance variable. Now this
>option is gone.
>I've tried using a semaphore that get's locked when the programm's up. But
>it still can happen, that the program starts up more than once when multiple
>prgram spawns occur very rapidly. The program then did not get enough
>startup-time to create and lock the semaphore.
>Is there ANY solution to this problem?
>
>Any hint into a possibly right direction would be greatly appreciated!
>
>Alois
This is how to do it. This method uses the application class name to
prevent multiple instances. If you want to change the name of your class
to something other than the app name, then replace all three items with
^^^^^^ under them to the same variable/literal. If you have problems
with this code then email me.
In CMainFrame
=============
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
cs.lpszClass=AfxGetAppName();
^^^^^^^^^^^^^^^
return CFrameWnd::PreCreateWindow(cs);
}
In CYourApp
===========
static BOOL bReg = FALSE;
BOOL CYourApp::InitInstance()
{
// Only allow one instance - if one already exists bring
// it to the top and make it active.
if (!CheckFirst()) return FALSE;
// Register my class using my name
WNDCLASS wndclass;
memset(&wndclass,0,sizeof(WNDCLASS));
*****YOUR STYLES MAY REPLACE THOSE BELOW*******
wndclass.style=CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc= ::DefWindowProc;
wndclass.hInstance=AfxGetInstanceHandle();
wndclass.hIcon=LoadIcon(IDR_MAINFRAME);
wndclass.hCursor=LoadCursor(IDC_ARROW);
wndclass.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
wndclass.lpszClassName=m_pszAppName;
^^^^^^^^^^^^
if (!AfxRegisterClass(&wndclass)) return FALSE;
// Set a flag to show we've done it
bReg=TRUE;
******THE REST OF INITINSTANCE GOES HERE*********
}
int CYourApp::ExitInstance()
{
// If I registered my class, unregister it
if (bReg) UnregisterClass(m_pszAppName,AfxGetInstanceHandle());
^^^^^^^^^^^^
return CWinApp::ExitInstance();
}
// This function check's to see if there is another window of my
// class. If there is, bring it and any children or popups to the top
// and activate it. Returns TRUE if this instance is the first.
BOOL CYourApp::CheckFirst()
{
CWnd* wndPrev;
CWnd* wndChild;
if (wndPrev=CWnd::FindWindow(m_pszAppName,NULL))
{
wndChild=wndPrev->GetLastActivePopup();
if (wndPrev->IsIconic()) wndPrev-ShowWindow(SW_RESTORE);
wndChild->SetForegroundWindow();
return FALSE;
}
return TRUE;
}
Add to the header file for CYourApp
===================================
BOOL CheckFirst();
--
Richard Baldwin
Re: How to avoid multiple instances of a program in NT and 95?
Author: Mickey Williams
Date: Mon, 03 Feb 1997 00:00
Date: Mon, 03 Feb 1997 00:00
21 lines
1790 bytes
1790 bytes
Alois Buecherl <Alois.Buecherl@terraSat.de> wrote in article <5d4eeb$n6u$1@euler.space.net>... > Hello, > I've been striving for so long now to find a SAVE way to start only one > instance of my C++ program under Windows NT and 95. As you might recall, this > used to be that easy in Windows 3.1 using the prevInstance variable. Now this > option is gone. > I've tried using a semaphore that get's locked when the programm's up. But > it still can happen, that the program starts up more than once when multiple > prgram spawns occur very rapidly. The program then did not get enough > startup-time to create and lock the semaphore. > Is there ANY solution to this problem? Create a mutex when your program starts up. GetLastError will return ERROR_ALREADY_EXISTS if the mutex name is already created. -- Mickey Williams Co Author - Programming Windows NT Unleashed Author - Essential Visual C++, Develop a Professional Visual C++ Application in 21 Days
Re: How to avoid multiple instances of a program in NT and 95?
Author: Raymond Chen
Date: Tue, 04 Feb 1997 00:00
Date: Tue, 04 Feb 1997 00:00
16 lines
1411 bytes
1411 bytes
>BOOL CYourApp::CheckFirst()
>{
> CWnd* wndPrev;
> CWnd* wndChild;
> if (wndPrev=CWnd::FindWindow(m_pszAppName,NULL))
> {
This still won't work if a second instance is started before the
first gets a chance to create its window.
Create a named event and check if you get ERROR_ALREADY_EXISTS
from GetLastError.
--
(My return address is intentionally invalid; delete ".---" to get my real address.
My responses are not to be considered official technical support or advice.)
Re: How to avoid multiple instances of a program in NT and 95?
Author: Richard Baldwin
Date: Tue, 04 Feb 1997 00:00
Date: Tue, 04 Feb 1997 00:00
22 lines
1909 bytes
1909 bytes
In article <01bc11ec$dfe21120$b8bfabc7@pongo>, Mickey Williams <mickeyw@deltanet.com> writes >Alois Buecherl <Alois.Buecherl@terraSat.de> wrote in article <5d4eeb$n6u$1@euler >.space.net>... >> Hello, >> I've been striving for so long now to find a SAVE way to start only one >> instance of my C++ program under Windows NT and 95. As you might recall, this >> used to be that easy in Windows 3.1 using the prevInstance variable. Now this >> option is gone. >> I've tried using a semaphore that get's locked when the programm's up. But >> it still can happen, that the program starts up more than once when multiple >> prgram spawns occur very rapidly. The program then did not get enough >> startup-time to create and lock the semaphore. >> Is there ANY solution to this problem? > >Create a mutex when your program starts up. GetLastError will return >ERROR_ALREADY_EXISTS if the mutex name is already created. > Does this method work under Win32s? -- Richard Baldwin
Re: How to avoid multiple instances of a program in NT and 95?
Author: Sean Kennedy
Date: Tue, 04 Feb 1997 00:00
Date: Tue, 04 Feb 1997 00:00
9 lines
1094 bytes
1094 bytes
On Mon, 03 Feb 97 10:24:56 GMT, Alois.Buecherl@terraSat.de (Alois Buecherl) wrote: A terrible hack could be upon startup immediately create a file in the %TEMP% directory. If the create function returns a 'File exists' return, otherwise, continue. -Sean Kennedy
Re: How to avoid multiple instances of a program in NT and 95?
Author: Heiner Eichmann
Date: Wed, 05 Feb 1997 00:00
Date: Wed, 05 Feb 1997 00:00
29 lines
1647 bytes
1647 bytes
raymondc@microsoft.com.--- (Raymond Chen) wrote: >This still won't work if a second instance is started before the >first gets a chance to create its window. >Create a named event and check if you get ERROR_ALREADY_EXISTS >from GetLastError. Hi! What happens if the program crashes before it can release the event? It is improbably also possible that a different program uses the same name for an event. What about this: Open your own EXE file for read access and do not allow other tasks to open the file. If this fails someone als has a lock on this file and another instance is still running. Yours Heiner Eichmann Inst. of Quantum Optics University of Hanover, Germany h.eichmann@mbox.iqo.uni-hannover.de
Re: How to avoid multiple instances of a program in NT and 95?
Author: Seth Allen
Date: Wed, 05 Feb 1997 00:00
Date: Wed, 05 Feb 1997 00:00
12 lines
1514 bytes
1514 bytes
Sean Kennedy wrote: > A terrible hack could be upon startup immediately create a file in the > %TEMP% directory. If the create function returns a 'File exists' > return, otherwise, continue. This may be more terrible than you imagined. Do you intend that the program delete the file when it exits? What happens if the program crashes and the file is never deleted? In that case it would seem that the program could never be run again, unless the person running it was sophisticated enough to know to delete the file, and with most users that will never happen.
Re: How to avoid multiple instances of a program in NT and 95?
Author: Amol Deshpande
Date: Wed, 05 Feb 1997 00:00
Date: Wed, 05 Feb 1997 00:00
20 lines
1495 bytes
1495 bytes
In article <32f6d5ca.86355796@news.ecs.fullerton.edu>, skennedy@ecs.fullerton.edu says... > >On Mon, 03 Feb 97 10:24:56 GMT, Alois.Buecherl@terraSat.de (Alois >Buecherl) wrote: > >A terrible hack could be upon startup immediately create a file in the >%TEMP% directory. If the create function returns a 'File exists' >return, otherwise, continue. > >-Sean Kennedy you might be better of creating a named mutex that the program tries to accquire on startup. -amol -- The opinions expressed in this message are my own personal views and do not reflect the official views of Microsoft Corporation.
Re: How to avoid multiple instances of a program in NT and 95?
Author: Amol Deshpande
Date: Wed, 05 Feb 1997 00:00
Date: Wed, 05 Feb 1997 00:00
44 lines
2133 bytes
2133 bytes
In article <5da29d$bs$2@newsserver.rrzn.uni-hannover.de>, h.eichmann@mbox.iqo.uni-hannover.de says... > >raymondc@microsoft.com.--- (Raymond Chen) wrote: > > >>This still won't work if a second instance is started before the >>first gets a chance to create its window. > >>Create a named event and check if you get ERROR_ALREADY_EXISTS >>from GetLastError. > >Hi! > >What happens if the program crashes before it can release the event? >It is improbably also possible that a different program uses the same >name for an event. If the program crashes (terminates), the event is released. > >What about this: > >Open your own EXE file for read access and do not allow other >tasks to open the file. If this fails someone als has a lock on >this file and another instance is still running. > >Yours > > >Heiner Eichmann >Inst. of Quantum Optics >University of Hanover, Germany >h.eichmann@mbox.iqo.uni-hannover.de > But then I could always copy the .exe to a different name and run another instance. -amol -- The opinions expressed in this message are my own personal views and do not reflect the official views of Microsoft Corporation.
Re: How to avoid multiple instances of a program in NT and 95?
Author: Chris Becke
Date: Wed, 05 Feb 1997 00:00
Date: Wed, 05 Feb 1997 00:00
20 lines
1438 bytes
1438 bytes
Sean Kennedy <skennedy@ecs.fullerton.edu> wrote in article <32f6d5ca.86355796@news.ecs.fullerton.edu>... > On Mon, 03 Feb 97 10:24:56 GMT, Alois.Buecherl@terraSat.de (Alois > Buecherl) wrote: > > A terrible hack could be upon startup immediately create a file in the > %TEMP% directory. If the create function returns a 'File exists' > return, otherwise, continue. Or worse, make a small initialized data section, mark it as "Shared", and put a refrence counter in it =0; First app increment to 1; and instance check counter and abort if >= 1 Chris. -- chris@dbn.lia.net <http://www.dbn.lia.net/users/chris>
Re: How to avoid multiple instances of a program in NT and 95?
Author: Doug Stevens
Date: Wed, 05 Feb 1997 00:00
Date: Wed, 05 Feb 1997 00:00
13 lines
1541 bytes
1541 bytes
> raymondc@microsoft.com.--- (Raymond Chen) wrote: > >Create a named event and check if you get ERROR_ALREADY_EXISTS > >from GetLastError. Heiner Eichmann wrote: > What happens if the program crashes before it can release the event? > It is improbably also possible that a different program uses the same > name for an event. If the program crashes, any handles that it holds become abandoned. If you wait on them, the OS returns a WAIT_ABANDONED value, and if you try to create them, it will let you.
Re: How to avoid multiple instances of a program in NT and 95?
Author: Pete MacLiesh
Date: Thu, 06 Feb 1997 00:00
Date: Thu, 06 Feb 1997 00:00
56 lines
2623 bytes
2623 bytes
The following appears to work - it also restricts to a single instance
system-wide
on machines running citrix derived systems like WinDD.
Return is true if it succeeded in creating the mutex, FALSE if failed
because it's
already running
PMac
--
BOOL CheckandCreateMutex(const char * mutexName)
{
BOOL ret = FALSE;
// The nastiness here is because of multi-user NT derivatives ala Citrix.
// To make a global resource on these, \SYSTEM must be appended -- but
this
// fails on vanilla NT, so I try both (\SYSTEM first) ... because I cannot
// determine portably if the system is multi-user !!!
HANDLE hMutex1 = OpenMutex(MUTEX_ALL_ACCESS, FALSE, mutexName);
HANDLE hMutex2 = OpenMutex(MUTEX_ALL_ACCESS, FALSE, CString(mutexName) +
"\\SYSTEM");
if (hMutex1 == NULL && hMutex2 == NULL)
{
HANDLE hMutex = CreateMutex(0, TRUE, CString(mutexName) + "\\SYSTEM");
if (hMutex == NULL)
hMutex = CreateMutex(0, TRUE, mutexName);
DWORD err = GetLastError();
ret = !(hMutex == NULL || err == ERROR_ALREADY_EXISTS);
ASSERT(ret);
}
else
{
if (hMutex1)
CloseHandle(hMutex1);
if (hMutex2)
CloseHandle(hMutex2);
}
return ret;
}
--
________________________________________________________________
All Opinions are my own ... not necessarily those of my employer
________________________________________________________________
Peter MacLiesh * Email: pmac@synopsys.com
Synopsys Inc. * Phone: (415)694-4423
700A E. Middlefield Rd. * Fax: (415)694-1626
Mountain View, CA 94043 *
Re: How to avoid multiple instances of a program in NT and 95?
Author: Raymond Chen
Date: Thu, 06 Feb 1997 00:00
Date: Thu, 06 Feb 1997 00:00
18 lines
1619 bytes
1619 bytes
On Wed, 05 Feb 1997 13:38:05 GMT, h.eichmann@mbox.iqo.uni-hannover.de (Heiner Eichmann) wrote: >What happens if the program crashes before it can release the event? Windows automatically closes unclosed HANDLE objects when the application exits (either normally or abnormally). >It is improbably also possible that a different program uses the same >name for an event. If you use a GUID, then you can be pretty sure that no other program is using the same name. -- (My return address is intentionally invalid; delete ".---" to get my real address. My responses are not to be considered official technical support or advice.)
Re: How to avoid multiple instances of a program in NT and 95?
Author: Mario Schlesinger
Date: Thu, 06 Feb 1997 00:00
Date: Thu, 06 Feb 1997 00:00
32 lines
1862 bytes
1862 bytes
Someday (Mon, 03 Feb 97 10:24:56 GMT) someone
(Alois.Buecherl@terraSat.de (Alois Buecherl)) wrote:
>I've been striving for so long now to find a SAVE way to start only one
>instance of my C++ program under Windows NT and 95. As you might recall, this
>used to be that easy in Windows 3.1 using the prevInstance variable. Now this
>option is gone.
Most of the time, I'm just going the easy way:
hWnd = FindWindow( szNameOfMyMainWindowClass, NULL );
if ( hWnd ) {
BringWindowToTop( hWnd );
SetForegroundWindow( hWnd );
};
see 'ya
/\/\ario
* FIDO: 2:2480/141.15 *
* EMail: schlesinger@augsburg.baynet.de *
* Homepage: http://www.schlesi-edv.com *
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
Da ertoente eine Stimme und sagte: "Laechle und sei froh,
es koennte schlimmer kommen!"
Und ich laechelte und war froh - und es kam schlimmer.
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
Re: How to avoid multiple instances of a program in NT and 95?
Author: Slawomir Marczynski
Date: Fri, 07 Feb 1997 00:00
Date: Fri, 07 Feb 1997 00:00
17 lines
1603 bytes
1603 bytes
Richard Baldwin (richard@ormesci.demon.co.uk) wrote: : >I've been striving for so long now to find a SAVE way to start only one : >instance of my C++ program under Windows NT and 95. As you might recall, this : In CMainFrame : ============= : BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) There is also an example (I've forgotten this name) on BC5.01 CDROM with OWL instead MFC. -- Slawomir Marczynski (Mr) Institute of Physics, Technical University of Szczecin Al. Piastow 48/49, 70-310 Szczecin, Poland slawek@arcadia.inter.tuniv.szczecin.pl, tel:+(048-91)-494056
Re: How to avoid multiple instances of a program in NT and 95?
Author: Don Lance
Date: Sat, 08 Feb 1997 00:00
Date: Sat, 08 Feb 1997 00:00
45 lines
2892 bytes
2892 bytes
Alois.Buecherl@terraSat.de (Alois Buecherl) wrote: >Hello, >I've been striving for so long now to find a SAVE way to start only one >instance of my C++ program under Windows NT and 95. As you might recall, this >used to be that easy in Windows 3.1 using the prevInstance variable. Now this >option is gone. >I've tried using a semaphore that get's locked when the programm's up. But >it still can happen, that the program starts up more than once when multiple >prgram spawns occur very rapidly. The program then did not get enough >startup-time to create and lock the semaphore. >Is there ANY solution to this problem? > >Any hint into a possibly right direction would be greatly appreciated! > >Alois Here's what I did to solve the problem for one of my apps; it worked really well. As someone suggested, create a mutex kernel object that's exclusive for the app. When your app starts up, the first thing you should do is look to see if it's present. It is there, then you know you have an instance already running. If it's not, then it's the first instance and proceed with startup. You can enhance your program a little more by switching focus and bringing your app to the foreground when someone attempts to start a second instance. To handle this, have the app create a "wait" thread to wait for a created event object to become signalled. When the event becomes signalled, the wait thread maximizes its main window, switches its focus to the foreground, then waits once more. Note that you should check your pointer to the apps main window frame, as it could possibly be NULL during a set of "rapid-fire" clicks from the user. Since a thread wait has almost no overhead, you're not chewing up processor time with it. Now your app should check for the existance of the mutex, and if present, signal the previous app's event. The other app will come to front, while your new app exits. You might can optimize this technique a little more by using a single kernel object instead of two. Good luck.
Re: How to avoid multiple instances of a program in NT and 95?
Author: Horst Schmid
Date: Sun, 09 Feb 1997 00:00
Date: Sun, 09 Feb 1997 00:00
98 lines
4427 bytes
4427 bytes
Slawomir Marczynski wrote:
>
> Richard Baldwin (richard@ormesci.demon.co.uk) wrote:
> : >I've been striving for so long now to find a SAVE way to start only one
> : >instance of my C++ program under Windows NT and 95. As you might recall, this
>
> : In CMainFrame
> : =============
> : BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
>
> There is also an example (I've forgotten this name) on BC5.01 CDROM
> with OWL instead MFC.
>
> --
> Slawomir Marczynski (Mr)
> Institute of Physics, Technical University of Szczecin
> Al. Piastow 48/49, 70-310 Szczecin, Poland
> slawek@arcadia.inter.tuniv.szczecin.pl, tel:+(048-91)-494056
For Delphi programmers I have a solution that ask user in case of starting the 2nd time to switch
to the first or to cancel:
Horst Schmid, http://ourworld.compuserve.com/homepages/Horst_Schmid
unit once; {Ask User to switch to the first Instance instead of starting a second}
{Simply add this Unit to your uses-Statement of your Delphi2.0-Project.dpr
to prevent starting Your App. more than once!}
interface
const Titel:pchar='Warning'; {You can change this to whatever you want}
Msg:String='App. %s is already running, switch to it?';
implementation
uses windows,sysutils,tlhelp32;
procedure SwitchToThisWindow(h1:hWnd; x:bool);stdCall; external user32 name 'SwitchToThisWindow';
{x=false: Size unchanged, x=true: normal size}
function EnumThreadWndProc(h1:hWnd;LPARAM:lParam):bool;stdCall; {Callback}
var hp:word;
begin
if IsWindowVisible(h1) then begin
hp:=GetLastActivePopup(h1);
if IsWindow(hp) then begin
SwitchToThisWindow(hp,true);
end end;
EnumThreadWndProc:=true;
end;
var mHandle: THandle; // Mutexhandle
s:string;
i:integer;
b:bool;
h,h2:tHandle;
lppe: TProcessEntry32;
lpte: TThreadEntry32;
pid0,tid:dWord;
x:array[0..255]of char;
Initialization {called when App is started}
s:=ParamStr(0); {Progname as MutexName}
i:=length(s);
while (i>0) and (s[i]<>'\') do dec(i); {without Path}
mHandle := CreateMutex(nil,True,pchar(copy(s,i+1,255)));
if GetLastError = ERROR_ALREADY_EXISTS then begin // App is running
i:=MessageBox(0,pchar(Format(Msg,[copy(s,i+1,255)]))
,Titel,MB_ICONQUESTION+MB_OKCANCEL);
if i=IDOK then begin {find the other Task and bring to top}
tid:=0;
h:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
lppe.dwSize:=SizeOf(lppe);
b:=Process32First(h,lppe);
pid0:=GetCurrentProcess;
s:=s+#0; {make String to ASCIIZ}
while b do begin {Proccess-Loop}
if (StrComp(@s[1],lppe.szExeFile)=0)and(lppe.th32ProcessID<>pid0) then begin
h2:=CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0);
lpte.dwSize:=SizeOf(lpte);
b:=Thread32First(h2,lpte);
tid:=0;
while b do begin {Thread-Loop}
if lpte.th32OwnerProcessID=lppe.th32ProcessID then begin
tid:=lpte.th32ThreadID;
EnumThreadWindows(tid,@EnumThreadWndProc,0) end;
b:=Thread32Next(h2,lpte) end;
end
else b:=Process32Next(h,lppe) end;
CloseHandle(h2);
CloseHandle(h);
end;
halt;{Cancel second start. Delete this line if the the second Choice
should be to start a second App.}
end;
finalization {End of App:Delete Mutex}
if mHandle <> 0 then CloseHandle(mHandle)
end.
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads