:: dostuff.bat
@echo off
:: insert long-running process call here
: End
What can I add to this batch file to make it terminate if it's already running in another process when it's executed?
:: dostuff.bat
@echo off
:: insert long-running process call here
: End
What can I add to this batch file to make it terminate if it's already running in another process when it's executed?
Well, if there can be only exactly one instance ever, then you can probably do this by creating a dummy file somewhere, probably in the temp directory:
copy NUL "%TEMP%\dostuff_is_doing_stuff.tmp"
you then remove it after you're done:
del "%TEMP%\dostuff_is_doing_stuff.tmp"
and at the start of the batch file you can check whether that file exists and exit accordingly:
if exist "%TEMP%\dostuff_is_doing_stuff.tmp" (
echo DoStuff is already running. Exiting ...
exit /b 1
)
Similarly, you can do that by changing the window title, which should also be more robust against a Ctrl+C'ed or crashed batch file.
Set the title:
title DoStuff
Re-set it afterwards:
title Not doing stuff
Check for it:
tasklist /FI "WINDOWTITLE eq DoStuff"
However, this has one problem: When cmd runs as administrator you'll get "Administrator: DoStuff" as the title. Which doesn't match anymore with tasklist
. You can hack-solve it by also checking for "Administrator: DoStuff" but that might look different depending on the Windows UI language, so it's probably not the best solution.
There is no way to do this in a clean way without using a custom external tool (You want something that creates a mutex AND runs (and waits for) your external command, this way, if the process is killed, the mutex dies with it)
Batch:
@echo off
echo starting long running process
REM calling dir here just to get a long running operation
onecmd.exe cmd.exe /C dir /S /B \*
echo done...bye
C++ helper app:
//Minimal error checking in this sample ;)
#include <Windows.h>
#include <TCHAR.h>
int main()
{
const TCHAR myguid[]=_T("50D6C9DA-8135-42de-ACFE-EC223C214DD7");
PROCESS_INFORMATION pi;
STARTUPINFO si={sizeof(STARTUPINFO)};
HANDLE mutex=CreateMutex(NULL,true,myguid);
DWORD gle=GetLastError();
if (!mutex || gle==ERROR_ALREADY_EXISTS)
{
CloseHandle(mutex);
return gle;
}
TCHAR*p=GetCommandLine();
if (*p=='"' && *(++p)) {
while (*p && *p!='"')++p;if (*p)++p;
}
else
while (*p && *p!=' ')++p;
while(*p==' ')++p;
if (CreateProcess(0,p,0,0,false,0,0,0,&si,&pi))
{
DWORD ec;
WaitForSingleObject(pi.hProcess,INFINITE);
GetExitCodeProcess(pi.hProcess,&ec);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return ec;
}
gle=GetLastError();
CloseHandle(mutex);
return gle;
}