Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Single instance batch file?

:: 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?

like image 757
lance Avatar asked Nov 21 '25 04:11

lance


2 Answers

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.

like image 181
Joey Avatar answered Nov 23 '25 20:11

Joey


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;
}
like image 27
Anders Avatar answered Nov 23 '25 19:11

Anders



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!