Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Ensuring only one instance of an app using WMI

WMI

Ensuring only one instance of an app using WMI

by  ChrisRChamberlain  Posted    (Edited  )
The examples that follow utilise [link http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnanchor/html/anch_wmi.asp]Windows Management Instrumentation[/link] as an alternative means to prevent users launching multiple instances af an application.
Code:
[color blue]LOCAL llQuit[/color][color green]    
*!* Check for instance(s) of your application being loaded, using SYS(16) to determine application name and path[/color][color blue]
oManager = GETOBJECT([winmgmts:])
cQuery = [select * from win32_process where name='] ;
[tab]+ LOWER(JUSTSTEM(SYS(16,0))) ;
[tab]+ [.exe']
oResult = oManager.ExecQuery(cQuery)

IF oResult.Count > 1
[/color][color green]    
*!* At this point you can choose to abort loading your application should another instance of your application be loaded under the same executable name but from some other or this location. Put simply, any executable with the same name as the one currently loaded.

If so, remove the rest of the code within this IF ...ENDIF statement and replace it with 'llQuit = .T.'

Should you wish to prevent your application from being loaded [u]only[/u] from this location, but allow other applications with the same name to be loaded from other locations, then leave the following code as is.

What the following code does is to compare both executable name and path/executable name, as opposed to executable name only in the simpler version.

Should you wish to prevent a user from running your application under a different executable name, check if the user has renamed the executable by comparing a hard coded name, such as 'myapp.exe', (your original executable name), with LOWER(JUSTFNAME(SYS(16))) in your main.prg.

If they are not the same, advise the user to rename the executable to its original name through a MESSAGEBOX(), before aborting the application.
[/color][color blue]
[tab]FOR EACH objEvent IN oResult
[tab][tab]FOR EACH oProp In objEvent.Properties_
[tab][tab][tab]IF oProp.Name = [CommandLine]	;
[tab][tab][tab][tab][tab]AND LOWER(CHRTRAN(oProp.Value,["],[]));
[tab][tab][tab][tab][tab]= LOWER(CHRTRAN(SYS(16),["],[]))
[tab][tab][tab][tab]llQuit	=	.T.
[tab][tab][tab][tab]EXIT
[tab][tab][tab]ENDI	
[tab][tab]ENDFOR
[tab][tab]IF llQuit
[tab][tab][tab]EXIT
[tab][tab]ENDI
[tab]ENDFOR
ENDIF[/color][color green]
*!* Clean up[/color][color blue]
oManager = .NULL.
oResult = .NULL.
RELEASE cQuery, oResult, oManager

IF llQuit [/color][color green]&& Myapp.exe loaded twice[/color][color blue]
    QUIT
ENDI[/color]
If you have synchronous or asynchronous threads in a VFP app and want prevent a thread from being launched if the parent app is not running, then you can extend the first example code as follows.
Code:
[color blue]LOCAL llQuit[/color][color green]    
*!* Check for parentapp.exe being loaded, not using SYS(16) to determine name of application. If you want to check the path as well as the filename, use a modified version of the code posted in the first example[/color][color blue]
oManager = GETOBJECT([winmgmts:])
oApps = oManager.InstancesOf([win32_process])

llQuit = .T.
FOR EACH PROCESS IN oApps
[tab]IF [parentapp.exe] = LOWER(PROCESS.Name)
[tab][tab]llQuit = .F.
[tab][tab]EXIT
[tab]ENDIF
NEXT

IF !llQuit
[tab]cQuery = [select * from win32_process where name='childapp.exe']
[tab]oResult = oManager.ExecQuery(cQuery)
[tab]IF oResult.Count > 1
[tab][tab]llQuit = .T.
[tab]oResult = .NULL.
[tab]ENDI
ENDI[/color][color green]

*!* Clean up[/color][color blue]
oApps = .NULL.
oManager = .NULL.

RELEASE cQuery, oApps, oResult, oManager

IF llQuit [/color][color green]&& parentapp.exe not being loaded or childapp.exe being loaded twice[/color][color blue]
    QUIT
ENDI[/color]
It also prevents curious users, bless 'em [wink], from attempting to run childapp.exe from Windows.

This does assume that the Windows Management Instrumentation Service has not been stopped or disabled.

You should error trap the example code if you consider that is a real possibility, and use an alternative method.

FAQ184-2483 - answering getting answered.​
Chris [pc2]
[link http://www.pdfcommander.net]PDFcommander[sup]tm[/sup].net[/link]
[link http://www.pdfcommander.net]PDFcommander[sup]tm[/sup].com[/link]
Register to rate this FAQ  : BAD 1 2 3 4 5 6 7 8 9 10 GOOD
Please Note: 1 is Bad, 10 is Good :-)

Part and Inventory Search

Back
Top