Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

How to prevent multiple launch of a program from Explorer window ?

Hello.
It appears that programs still launches twice because while the *.btm file is running the second copy launches as well. So, how to detect running *.btm file ?

thanks
 
Any program or one program? Any BTM or one BTM (what does it do?)? Steps to reproduce the error.
One BTM - which checks if another copy of itself is running.

There is no error - the first copy of BTM (As per advice above) works fine but the second works fine as well and each starts the relevant program (MSAccess). This is because execution of BTM takes more time than for OS to launch the second copy of the BTM file. I know that I can adjust the mouse settings, but do not want to do this yet.
 
Your post #31 appeared at the top of page 2. I thought it was the beginning of this thread. I apologize for that.

How about using a "sentinel" file in %TEMP to tell the BTM that it is already running? That should be faster than testing whether the app is running. This, below, works if I double-click the shortcut twice as fast as I can. Winword is only run once.

Code:
REM NOTTWICE.BTM
if exist %temp\not_twice_sentinel.txt quit
touch /q /c %temp\not_twice_sentinel.txt
start /wait winword
REM do other things when winword terminates
del /q %temp\not_twice_sentinel.txt
 
Apparently you can use a user environment variable as a sentinel. This works.

Code:
REM NOTTWICE.BTM
if defined not_twice_sentinel exit
set /u not_twice_sentinel=1
start /wait winword
REM do other stuff when winword terminates
unset /u not_twice_sentinel

My BTM association uses "/c".

Code:
v:\> ftype tcc.batch
tcc.batch="D:\tc28\tcc.exe" /c "%1" %*

And my shortcut looks like this.

1670524538993.png
 
Last edited:
Apparently you can use a user environment variable as a sentinel. This works.

Code:
REM NOTTWICE.BTM
if defined not_twice_sentinel exit
set /u not_twice_sentinel=1
start /wait winword
REM do other stuff when winword terminates
unset /u not_twice_sentinel

Maybe add a window hide before the start ?
 
Apparently you can use a user environment variable as a sentinel. This works.
I'm having some trouble with the user environment approach. I suggest you use the temp file as I suggested first.
 
Hey @vefatica,
What about using the Window Title as a sentinel?
Code:
@setlocal
@echo off
if defined titleprompt unset titleprompt
set theTitle=Working...
echo @winpid  : %@winpid[%theTitle]
iff %@winpid[%theTitle] gt 0 then
  echo A window with this title already exists.
else
  echo This .BTM is running in a window with a unique window title.
  title %theTitle
endiff
pause
title Ready.
endlocal

Joe

EDIT: I see that this has been done previously.
 
Last edited:
Hey @vefatica,
What about using the Window Title as a sentinel?
Code:
@setlocal
@echo off
if defined titleprompt unset titleprompt
set theTitle=Working...
echo @winpid  : %@winpid[%theTitle]
iff %@winpid[%theTitle] gt 0 then
  echo A window with this title already exists.
else
  echo This .BTM is running in a window with a unique window title.
  title %theTitle
endiff
pause
title Ready.
endlocal

Joe

EDIT: I see that this has been done previously.
That seems to work. I don't understand why unsetting TITLEPROMPT matters (it does). When started from a shortcut, there are no prompts involved and I thought TITLEPROMPT was only used when a prompt was issued.
 
I'm having some trouble with the user environment approach. I suggest you use the temp file as I suggested first.
Thanks for the idea. I should have thought about this myself as I've used this long time ago (are they also call flags ?). I also thought that using variable could be problematic as I do not fully understand where which variables are stored - does each shortcut runs its onw environment, etc.

BTW You use exit and quit (and both work) - but which approach is right ?
 
Last edited:
Hello again
The temp file approach works, but not always as the program sometimes manages to launch for the second time before the temp file is written to hard drive... I tried the environmental variable approach but it does not work:


------------msaccess-launch.btm------------[this is in my shorcut, new code is indented]

if "%flagma%"="1" then quit​
detach msaccess.btm

quit
------------------

=============================================

--------msaccess.btm---------

set flagma="1"​

"C:\Office\\MSACCESS.EXE" c:\d.mdb
c:\bat\bsa.bat

set flagma=""​
-----------------------------------
 
Last edited:
It applies to the window from which the .btm was started.

Put the following code into a .btm file,
for example, test.btm
Code:
@setlocal
@echo off
if defined titleprompt unset titleprompt
set theTitle=Working...
echo @winpid  : %@winpid[%theTitle]
iff %@winpid[%theTitle] gt 0 then
  echo A window with this title already exists.
  :: We won't be running MS-ACCESS.EXE
else
  echo This .BTM is running in a window with a unique window title.
  title %theTitle
  ::Put the code that you want to run only once in this section of the iff
  ::For example, MS-ACCESS.EXE
  pause Launching MS Access. Press any key to continue...
endiff
pause %_batchname complete. Press any key to continue...
title Ready.
endlocal

From Windows Explorer,
double-click on the test.btm file to launch it.

On my system, this is what I get;
1682540053226.png


Now, from Windows Explorer,
double-click on the test.btm to launch it again.

On my system, this is what I get;
1682540077738.png


The first run, the Window title is changed to Working...

The second run,
we are told that a Window with the title Working... already exists.

This is because there is already a Window called Working...

No matter how many times you double-click on test.btm,
it will not allow you to run a second instance,
as the Window with the title Working...
already exists.

The Window title Working... is unique.
What is even more unique is the process ID for the window with the specified title.
The process ID for the Window is unique.
That is, there can only be one process ID for the Window.

The %@winpid[] is the variable
that I am using
to make sure that only one instance
of the test.btm is run at one time.

Please give it a try,
and see if it does what you want.

Joe
 
Last edited:
Thanks. Corrections to your code: you lauch the program before displaying message that it will be loaded... Then you change the title back without checking that the program has terminated - so it does not work...

My code to launch is "detach msaccess.btm", so the window title should change when everything terminates (and msaccess.btm calls another bat file which does the archice/backup work after MSAccess is closed) and I do not need any extra open windows whether with prompts or not. So I do have a code which hides all extra windows except MSAccess but it relies on sentinel file which is slow.

Once again - using pure variable seem more beneficial as I use the same code to launch different programs concurrently and only one copy of each should launch.

Finally, I still do not understand what is the window in which the program is running - is it the terminal window which displays the pause prompt, is it MSAccess.exe itself, my msaccess.btm file/another bat file which is called from within it... Will the window change depending on whether I launch your file from shortcut or from FAR prompt, etc.
 

Similar threads

Back
Top