8
1
I have a batch script which is run from an AT command, and may get run more than once. When it starts, I need it to detect if it already running, and if so, exit (the second one) immediately.
- It must be robust, and handle if the scripts exits unexpectedly (i.e. so I can't set a flag on entry and clear it on exit)
- It must run in a Remote Desktop session
- I'm stuck on XP with Powershell v2, but don't mind writing a little exe if I can't do it in batch/powershell or vbs
- The script must run minimised, so I start it with Start "NAME" /MIN %COMSPEC% /C "MyScript.bat"
- Other cmd windows may be open so I need to check the running script
- The batch script runs as SYSTEM user, but I can't use any WMI
I was using PowerShell Get-Process to look at MainWindowTitle, but this didn't work when remote connecting to the computer as the script may be running, but not displayed in this remote connection instance. I this case, the cmd process is seen by Get-Process, but the MainWindowTitle is blank.
I've tried Get-Process and looked at the expanded StartInfo.EnvironmentVariables property, but can't see how to create an env var so that it appears in the property.
I thought about using /WAIT in the start command, then the AT will remain open until it finishes, but the script containing the AT is not minimised
Any ideas?
Use a "lockfile". Create a file when you start the script and delete it when you finish. Before creating it check whether it already exists. If it already exists you are in a second batch file so exit. – DavidPostill – 2016-02-03T10:43:02.207
@DavidPostill I think their first point may be a problem with that, in that if the script fails the lock file won't be removed - Depending on how it fails, I guess. – Jonno – 2016-02-03T10:43:50.927
@Jonno That's easily gotten around. if the file already exists and is older than the current time (by some configurable difference) then assume a crash and delete the lock file. Then create a new one. – DavidPostill – 2016-02-03T10:45:55.693
@DavidPostill Could be a solution - OP, do you have any more information on what your scripts are actually doing? Should it be complete within seconds, minutes, hours? Is it invariable enough that a time scope could be used? How can it fail - would it likely be gracefully enough that a delete on the lock could be handled after a failure regardless, EG, if it fails does it at least close itself, so you could call a batch to open a lock, run your script, then delete your lock, regardless of the script result? – Jonno – 2016-02-03T10:48:35.270
Thanks for your input. The script could take hours, I'm afraid, and batch errors aren't really trappable – FrinkTheBrave – 2016-02-03T10:50:16.043
One other thought - you specify the title with the
"NAME"
command in start but it doesn't work in some situations. What if you use the commandtitle name
in your batch file, does it carry across then? EG, add it as the first line of your batch and then don't specify it from yourstart
command. – Jonno – 2016-02-03T10:50:47.3471
You could also use the PID as the lockfile filename. If the PID doesn't match exit the second batch file. See how to get own process pid from the command prompt in windows for code to get the PID. That script also uses a lock "The script establishes an exclusive lock on a temporary file that incorporates the current time into the name. There can only be a collision if two like named batch processes attempt to get the PID within the same 0.01 second time interval, in which case only one will succeed."
– DavidPostill – 2016-02-03T10:52:08.047@Jonno no, it doesn't matter how the title is set, the Get-Process information doesn't include it when it's running in another session – FrinkTheBrave – 2016-02-03T10:52:16.597
@FrinkTheBrave What's wrong with lockfile approach? Note my second comment about handling a crash, and my third comment about using the PID. – DavidPostill – 2016-02-03T11:01:49.297
@DavidPostill I'll look into a lockfile. If I store the PID in it, I can check for that process still running. If it's not, then it must have exited unexpectedly. I can't use your time idea as it could be hours, and I can't use that PID link as it uses WMI. I'll think of a way to get the PID. Maybe list all the CMD PIDs, start my cms and see what PID has been added. Or write a little vbs launcher script... – FrinkTheBrave – 2016-02-03T14:22:18.827