Run one copy per connection over RDP & WTS

Started by Jeremy Whilde, December 16, 2015, 06:52:29 AM

Previous topic - Next topic

Jeremy Whilde

Is there a way to allow only one copy of a compiled WB exe to run per connected session where the exe is on a terminal server or if the exe is on a PC that also has an additional user PC connected by RDP?

So if our compiled program is running on a terminal server then each client can only run one copy and if our program is running on a none TS machine but a second user needs to run only a single instance when connected by RDP can this be achieved?.

So if I try to use any of the normal methods such as:

If WinExist("OurProgram") == @TRUE Then Exit
WinTitle("", "OurProgram")
; Program code

This does not work for the above it will only allow 1 instance (copy of the program) to run. Same for all the other methods here: http://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/tsleft.web+winbatch/Launching~WinBatch~and~Other~Apps+Prevent~more~than~one~WB~Copy~from~Being~Run.txt

Thanks JW

td

Please read the following topic in this forum:

http://forum.winbatch.com/index.php?topic=1543.0

Note that the OP's final solutions using GetTickCount will not work in all cases but using the solutions that involve the session start time and id should.   
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

One simple approach to obtaining the session id and logon time:

Code (winbatch) Select
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; GetSessionIdTime
;;
;; Input  - pointers to variables to receive id
;;          and time.
;; Output - current process's session id and
;;          session start time.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#DefineFunction GetSessionIdTime(_pSessionId, _pStartTime)
   AddExtender( "WWWTS44I.DLL" , 0, "WWWTS64I.DLL" )

   ; Error handling not inculded.
   nProcessId   = DllCall("Kernel32.Dll",long:"GetCurrentProcessId")
   nSessionId   = wtsProcIdToSessId(nProcessId)
   aResult      = wtsQuerySessionInfo("", nSessionId)
   *_pSessionId = nSessionId
   *_pStartTime = aResult[19] ;  Time is UTC
   
   return 1
#EndFunction


; Test
SessiontId = 0
StartTime  = 0

GetSessionIdTime(&SessionId, &StartTime)
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

An unpolished example of how run-once-per-session might be implemented using the above session information UDF:

Code (winbatch) Select
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; GetSessionIdTime
;;
;; Input  - pointers to variables to receive id
;;          and time.
;; Output - current process's sesstion id and
;;          session start time.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#DefineFunction GetSessionIdTime(_pSessionId, _pStartTime)
   AddExtender( "WWWTS44I.DLL" , 0, "WWWTS64I.DLL" )

   ; Error handling not inculded.
   nProcessId   = DllCall("Kernel32.Dll",long:"GetCurrentProcessId")
   nSessionId   = wtsProcIdToSessId(nProcessId)
   aResult      = wtsQuerySessionInfo("", nSessionId)
   *_pSessionId = nSessionId
   *_pStartTime = aResult[19] ;  Time is UTC
   
   return 1
#EndFunction

; Create  an ini file name+path in an accessible location.
strScript = FileRoot(IntControl (1004, 0, 0, 0, 0))
strAppIni = ShortcutDir( "{F1B32785-6FBA-4FCF-9D55-7B8E7F157091}", 0, 1)
strAppIni := strScript:".ini"

; Get the session info.
SessionId = 0
StartTime  = 0
GetSessionIdTime(&SessionId, &StartTime)

; Check if first run of session.
LastTime = IniReadPvt(strScript, SessionId, "", strAppIni) 
if LastTime == StartTime then exit
else IniWritePvt(strScript, SessionId, StartTime, strAppIni)

; Should see this only once per session.
Message("Hello", "World")
exit


"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade