Batch file to delete calling program and then itself

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
7
down vote

favorite
2












There are times when I want to run a one-off executable on an end-user's machine that cleans up after itself, i.e. deletes itself without a trace. An exe can't delete itself because an exe can't be deleted while it's running. However, a batch file can delete itself, presumably because its contents get copied so the file can close before the code gets run.



So what if there was a general-purpose batch file that deletes the calling executable and then deletes itself? I couldn't find such a batch file so I made one, thinking maybe it could be useful to others. And obviously I want to see if it can be improved upon, of course.



This is particularly useful for an NSIS installer because the batch file can be embedded in the exe and then extracted.



Make sure you copy the batch file before you test it because it will delete itself!



@ECHO OFF

SET filename=%~nx1

IF "%filename%"=="" GOTO:EOF

TASKKILL /IM "%filename%" /F

:LOOP
TASKLIST | FIND /I "%filename%" >NUL 2>&1
IF ERRORLEVEL 1 (
GOTO CONTINUE
) ELSE (
ECHO %filename% is still running
PING -n 6 127.0.0.1>NUL
GOTO LOOP
)

:CONTINUE

DEL /F "%~f1"
DEL /F "%~f0"


I figured the easiest way to get the path of the calling program is to just have it passed in as a parameter. The IF "%filename%"=="" GOTO:EOF is very important because if the first parameter isn't defined then DEL /F "%~f1" will automatically act like a * is there and try to delete the contents of the whole folder.







share|improve this question

















  • 2




    I have rolled back the last edit. Please see what you may and may not do after receiving answers.
    – Vogel612♦
    May 3 at 19:34










  • Oops, sorry! I should have known better.
    – Kyle Delaney
    May 4 at 21:06
















up vote
7
down vote

favorite
2












There are times when I want to run a one-off executable on an end-user's machine that cleans up after itself, i.e. deletes itself without a trace. An exe can't delete itself because an exe can't be deleted while it's running. However, a batch file can delete itself, presumably because its contents get copied so the file can close before the code gets run.



So what if there was a general-purpose batch file that deletes the calling executable and then deletes itself? I couldn't find such a batch file so I made one, thinking maybe it could be useful to others. And obviously I want to see if it can be improved upon, of course.



This is particularly useful for an NSIS installer because the batch file can be embedded in the exe and then extracted.



Make sure you copy the batch file before you test it because it will delete itself!



@ECHO OFF

SET filename=%~nx1

IF "%filename%"=="" GOTO:EOF

TASKKILL /IM "%filename%" /F

:LOOP
TASKLIST | FIND /I "%filename%" >NUL 2>&1
IF ERRORLEVEL 1 (
GOTO CONTINUE
) ELSE (
ECHO %filename% is still running
PING -n 6 127.0.0.1>NUL
GOTO LOOP
)

:CONTINUE

DEL /F "%~f1"
DEL /F "%~f0"


I figured the easiest way to get the path of the calling program is to just have it passed in as a parameter. The IF "%filename%"=="" GOTO:EOF is very important because if the first parameter isn't defined then DEL /F "%~f1" will automatically act like a * is there and try to delete the contents of the whole folder.







share|improve this question

















  • 2




    I have rolled back the last edit. Please see what you may and may not do after receiving answers.
    – Vogel612♦
    May 3 at 19:34










  • Oops, sorry! I should have known better.
    – Kyle Delaney
    May 4 at 21:06












up vote
7
down vote

favorite
2









up vote
7
down vote

favorite
2






2





There are times when I want to run a one-off executable on an end-user's machine that cleans up after itself, i.e. deletes itself without a trace. An exe can't delete itself because an exe can't be deleted while it's running. However, a batch file can delete itself, presumably because its contents get copied so the file can close before the code gets run.



So what if there was a general-purpose batch file that deletes the calling executable and then deletes itself? I couldn't find such a batch file so I made one, thinking maybe it could be useful to others. And obviously I want to see if it can be improved upon, of course.



This is particularly useful for an NSIS installer because the batch file can be embedded in the exe and then extracted.



Make sure you copy the batch file before you test it because it will delete itself!



@ECHO OFF

SET filename=%~nx1

IF "%filename%"=="" GOTO:EOF

TASKKILL /IM "%filename%" /F

:LOOP
TASKLIST | FIND /I "%filename%" >NUL 2>&1
IF ERRORLEVEL 1 (
GOTO CONTINUE
) ELSE (
ECHO %filename% is still running
PING -n 6 127.0.0.1>NUL
GOTO LOOP
)

:CONTINUE

DEL /F "%~f1"
DEL /F "%~f0"


I figured the easiest way to get the path of the calling program is to just have it passed in as a parameter. The IF "%filename%"=="" GOTO:EOF is very important because if the first parameter isn't defined then DEL /F "%~f1" will automatically act like a * is there and try to delete the contents of the whole folder.







share|improve this question













There are times when I want to run a one-off executable on an end-user's machine that cleans up after itself, i.e. deletes itself without a trace. An exe can't delete itself because an exe can't be deleted while it's running. However, a batch file can delete itself, presumably because its contents get copied so the file can close before the code gets run.



So what if there was a general-purpose batch file that deletes the calling executable and then deletes itself? I couldn't find such a batch file so I made one, thinking maybe it could be useful to others. And obviously I want to see if it can be improved upon, of course.



This is particularly useful for an NSIS installer because the batch file can be embedded in the exe and then extracted.



Make sure you copy the batch file before you test it because it will delete itself!



@ECHO OFF

SET filename=%~nx1

IF "%filename%"=="" GOTO:EOF

TASKKILL /IM "%filename%" /F

:LOOP
TASKLIST | FIND /I "%filename%" >NUL 2>&1
IF ERRORLEVEL 1 (
GOTO CONTINUE
) ELSE (
ECHO %filename% is still running
PING -n 6 127.0.0.1>NUL
GOTO LOOP
)

:CONTINUE

DEL /F "%~f1"
DEL /F "%~f0"


I figured the easiest way to get the path of the calling program is to just have it passed in as a parameter. The IF "%filename%"=="" GOTO:EOF is very important because if the first parameter isn't defined then DEL /F "%~f1" will automatically act like a * is there and try to delete the contents of the whole folder.









share|improve this question












share|improve this question




share|improve this question








edited Jul 13 at 1:09
























asked May 2 at 18:27









Kyle Delaney

1636




1636







  • 2




    I have rolled back the last edit. Please see what you may and may not do after receiving answers.
    – Vogel612♦
    May 3 at 19:34










  • Oops, sorry! I should have known better.
    – Kyle Delaney
    May 4 at 21:06












  • 2




    I have rolled back the last edit. Please see what you may and may not do after receiving answers.
    – Vogel612♦
    May 3 at 19:34










  • Oops, sorry! I should have known better.
    – Kyle Delaney
    May 4 at 21:06







2




2




I have rolled back the last edit. Please see what you may and may not do after receiving answers.
– Vogel612♦
May 3 at 19:34




I have rolled back the last edit. Please see what you may and may not do after receiving answers.
– Vogel612♦
May 3 at 19:34












Oops, sorry! I should have known better.
– Kyle Delaney
May 4 at 21:06




Oops, sorry! I should have known better.
– Kyle Delaney
May 4 at 21:06










2 Answers
2






active

oldest

votes

















up vote
5
down vote



accepted










TASKKILL /IM "%filename%" /F


It makes sense that you might want to do this, but I expect the file would be more useful if it waited for its calling program to end on its own. That way we can be sure the calling executable is done with everything else, including releasing any resources it's holding. Because you already have looping code checking for the process, this should be as simple as removing the line.




Comments would be great.



For example, I understand that PING -n 6 127.0.0.1>NUL is a fairly common delaying tactic, but it's still downright odd if you haven't seen it before.




Likewise filename manipulations (%~nx1 and such) will always be arcane. A comment saying that it pulls out the name and extension would be appreciated.



There's an alternative here, which is a bit of a cheat but worth mentioning as potentially safer in some cases. Because the use case of this batch file is that it's created by the executable that wants cleaning up, that executable could do the text substitution and put its own filename directly into the relevant code of the batch file. Obviously this depends on the language that the executable is written in having good string manipulation capabilties, but it would help protect against deleting whole folders and other such disasters.




GOTO CONTINUE


Personally, I would not have called it 'CONTINUE' because in many C family languages continue would continue with the next iteration of a loop, rather than break out of it. Obviously it makes no difference to the script, and it's not something that a pure batch programmer would trip over. I just found it slightly jarring, and thought I'd mention it.




) ELSE (


This is not clear cut, but some people find it easier to read if the else is omitted when the if side breaks, returns, or otherwise interupts the control flow. That is



:LOOP
TASKLIST | FIND /I "%filename%" >NUL 2>&1
IF ERRORLEVEL 1 (
GOTO CONTINUE
)
ECHO %filename% is still running
PING -n 6 127.0.0.1>NUL
GOTO LOOP


Alternatively, you could swap the test around and avoid the goto CONTINUE altogether.



:LOOP
TASKLIST | FIND /I "%filename%" >NUL 2>&1
IF ERRORLEVEL 0 (
ECHO %filename% is still running
PING -n 6 127.0.0.1>NUL
GOTO LOOP
)


I would personally find that easier to read as the batch magic equivalent of a conventional spin lock style construction.






share|improve this answer























  • Ah yes, I like your loop better. I had taken most of that "wait" code from another post.
    – Kyle Delaney
    May 2 at 20:04

















up vote
1
down vote













I've applied Josiah's suggestions.



I added a kill switch rather than removing the TASKKILL because there are cases where an application runs a batch file and waits for it to exit so the application wouldn't just end on its own. For example, in NSIS I'm using nsExec::Exec to run the batch file silently.



As for the idea about the calling program inserting its path into the batch file
directly, I'll leave that up to whoever writes the calling program. The current parameter implementation can serve as placeholders for that. But note that if the first parameter is omitted the kill switch won't work in the current design, so if direct placement is implemented then the kill switch should be changed as well.



@ECHO OFF

rem // This is needed for GOTO:EOF or EXIT /B
SETLOCAL EnableExtensions

rem // Pull out the name/extension from the path provided in the first parameter
rem // Ex: C:Folderfile.exe becomes file.exe
SET filename=%~nx1

rem // Exit if no parameter is provided
IF "%filename%"=="" EXIT /B

rem // Kill the task if second parameter is /kill (case-insensitive)
IF /I "%~2"=="/kill" TASKKILL /IM "%filename%" /F

:LOOP

rem // See if TASKLIST result contains the filename, while suppressing output
TASKLIST | FIND /I "%filename%" >NUL 2>&1

rem // %ERRORLEVEL% will be zero if the filename was found
IF ERRORLEVEL 0 (
ECHO %filename% is still running

rem // Wait for 5 seconds
PING -n 6 127.0.0.1>NUL

GOTO LOOP
)

rem // "%~f1" expands to the full path provided in the first parameter
DEL /F "%~f1"

rem // Delete this batch file
DEL /F "%~f0"





share|improve this answer





















    Your Answer




    StackExchange.ifUsing("editor", function ()
    return StackExchange.using("mathjaxEditing", function ()
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    );
    );
    , "mathjax-editing");

    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "196"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );








     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f193486%2fbatch-file-to-delete-calling-program-and-then-itself%23new-answer', 'question_page');

    );

    Post as a guest






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    5
    down vote



    accepted










    TASKKILL /IM "%filename%" /F


    It makes sense that you might want to do this, but I expect the file would be more useful if it waited for its calling program to end on its own. That way we can be sure the calling executable is done with everything else, including releasing any resources it's holding. Because you already have looping code checking for the process, this should be as simple as removing the line.




    Comments would be great.



    For example, I understand that PING -n 6 127.0.0.1>NUL is a fairly common delaying tactic, but it's still downright odd if you haven't seen it before.




    Likewise filename manipulations (%~nx1 and such) will always be arcane. A comment saying that it pulls out the name and extension would be appreciated.



    There's an alternative here, which is a bit of a cheat but worth mentioning as potentially safer in some cases. Because the use case of this batch file is that it's created by the executable that wants cleaning up, that executable could do the text substitution and put its own filename directly into the relevant code of the batch file. Obviously this depends on the language that the executable is written in having good string manipulation capabilties, but it would help protect against deleting whole folders and other such disasters.




    GOTO CONTINUE


    Personally, I would not have called it 'CONTINUE' because in many C family languages continue would continue with the next iteration of a loop, rather than break out of it. Obviously it makes no difference to the script, and it's not something that a pure batch programmer would trip over. I just found it slightly jarring, and thought I'd mention it.




    ) ELSE (


    This is not clear cut, but some people find it easier to read if the else is omitted when the if side breaks, returns, or otherwise interupts the control flow. That is



    :LOOP
    TASKLIST | FIND /I "%filename%" >NUL 2>&1
    IF ERRORLEVEL 1 (
    GOTO CONTINUE
    )
    ECHO %filename% is still running
    PING -n 6 127.0.0.1>NUL
    GOTO LOOP


    Alternatively, you could swap the test around and avoid the goto CONTINUE altogether.



    :LOOP
    TASKLIST | FIND /I "%filename%" >NUL 2>&1
    IF ERRORLEVEL 0 (
    ECHO %filename% is still running
    PING -n 6 127.0.0.1>NUL
    GOTO LOOP
    )


    I would personally find that easier to read as the batch magic equivalent of a conventional spin lock style construction.






    share|improve this answer























    • Ah yes, I like your loop better. I had taken most of that "wait" code from another post.
      – Kyle Delaney
      May 2 at 20:04














    up vote
    5
    down vote



    accepted










    TASKKILL /IM "%filename%" /F


    It makes sense that you might want to do this, but I expect the file would be more useful if it waited for its calling program to end on its own. That way we can be sure the calling executable is done with everything else, including releasing any resources it's holding. Because you already have looping code checking for the process, this should be as simple as removing the line.




    Comments would be great.



    For example, I understand that PING -n 6 127.0.0.1>NUL is a fairly common delaying tactic, but it's still downright odd if you haven't seen it before.




    Likewise filename manipulations (%~nx1 and such) will always be arcane. A comment saying that it pulls out the name and extension would be appreciated.



    There's an alternative here, which is a bit of a cheat but worth mentioning as potentially safer in some cases. Because the use case of this batch file is that it's created by the executable that wants cleaning up, that executable could do the text substitution and put its own filename directly into the relevant code of the batch file. Obviously this depends on the language that the executable is written in having good string manipulation capabilties, but it would help protect against deleting whole folders and other such disasters.




    GOTO CONTINUE


    Personally, I would not have called it 'CONTINUE' because in many C family languages continue would continue with the next iteration of a loop, rather than break out of it. Obviously it makes no difference to the script, and it's not something that a pure batch programmer would trip over. I just found it slightly jarring, and thought I'd mention it.




    ) ELSE (


    This is not clear cut, but some people find it easier to read if the else is omitted when the if side breaks, returns, or otherwise interupts the control flow. That is



    :LOOP
    TASKLIST | FIND /I "%filename%" >NUL 2>&1
    IF ERRORLEVEL 1 (
    GOTO CONTINUE
    )
    ECHO %filename% is still running
    PING -n 6 127.0.0.1>NUL
    GOTO LOOP


    Alternatively, you could swap the test around and avoid the goto CONTINUE altogether.



    :LOOP
    TASKLIST | FIND /I "%filename%" >NUL 2>&1
    IF ERRORLEVEL 0 (
    ECHO %filename% is still running
    PING -n 6 127.0.0.1>NUL
    GOTO LOOP
    )


    I would personally find that easier to read as the batch magic equivalent of a conventional spin lock style construction.






    share|improve this answer























    • Ah yes, I like your loop better. I had taken most of that "wait" code from another post.
      – Kyle Delaney
      May 2 at 20:04












    up vote
    5
    down vote



    accepted







    up vote
    5
    down vote



    accepted






    TASKKILL /IM "%filename%" /F


    It makes sense that you might want to do this, but I expect the file would be more useful if it waited for its calling program to end on its own. That way we can be sure the calling executable is done with everything else, including releasing any resources it's holding. Because you already have looping code checking for the process, this should be as simple as removing the line.




    Comments would be great.



    For example, I understand that PING -n 6 127.0.0.1>NUL is a fairly common delaying tactic, but it's still downright odd if you haven't seen it before.




    Likewise filename manipulations (%~nx1 and such) will always be arcane. A comment saying that it pulls out the name and extension would be appreciated.



    There's an alternative here, which is a bit of a cheat but worth mentioning as potentially safer in some cases. Because the use case of this batch file is that it's created by the executable that wants cleaning up, that executable could do the text substitution and put its own filename directly into the relevant code of the batch file. Obviously this depends on the language that the executable is written in having good string manipulation capabilties, but it would help protect against deleting whole folders and other such disasters.




    GOTO CONTINUE


    Personally, I would not have called it 'CONTINUE' because in many C family languages continue would continue with the next iteration of a loop, rather than break out of it. Obviously it makes no difference to the script, and it's not something that a pure batch programmer would trip over. I just found it slightly jarring, and thought I'd mention it.




    ) ELSE (


    This is not clear cut, but some people find it easier to read if the else is omitted when the if side breaks, returns, or otherwise interupts the control flow. That is



    :LOOP
    TASKLIST | FIND /I "%filename%" >NUL 2>&1
    IF ERRORLEVEL 1 (
    GOTO CONTINUE
    )
    ECHO %filename% is still running
    PING -n 6 127.0.0.1>NUL
    GOTO LOOP


    Alternatively, you could swap the test around and avoid the goto CONTINUE altogether.



    :LOOP
    TASKLIST | FIND /I "%filename%" >NUL 2>&1
    IF ERRORLEVEL 0 (
    ECHO %filename% is still running
    PING -n 6 127.0.0.1>NUL
    GOTO LOOP
    )


    I would personally find that easier to read as the batch magic equivalent of a conventional spin lock style construction.






    share|improve this answer















    TASKKILL /IM "%filename%" /F


    It makes sense that you might want to do this, but I expect the file would be more useful if it waited for its calling program to end on its own. That way we can be sure the calling executable is done with everything else, including releasing any resources it's holding. Because you already have looping code checking for the process, this should be as simple as removing the line.




    Comments would be great.



    For example, I understand that PING -n 6 127.0.0.1>NUL is a fairly common delaying tactic, but it's still downright odd if you haven't seen it before.




    Likewise filename manipulations (%~nx1 and such) will always be arcane. A comment saying that it pulls out the name and extension would be appreciated.



    There's an alternative here, which is a bit of a cheat but worth mentioning as potentially safer in some cases. Because the use case of this batch file is that it's created by the executable that wants cleaning up, that executable could do the text substitution and put its own filename directly into the relevant code of the batch file. Obviously this depends on the language that the executable is written in having good string manipulation capabilties, but it would help protect against deleting whole folders and other such disasters.




    GOTO CONTINUE


    Personally, I would not have called it 'CONTINUE' because in many C family languages continue would continue with the next iteration of a loop, rather than break out of it. Obviously it makes no difference to the script, and it's not something that a pure batch programmer would trip over. I just found it slightly jarring, and thought I'd mention it.




    ) ELSE (


    This is not clear cut, but some people find it easier to read if the else is omitted when the if side breaks, returns, or otherwise interupts the control flow. That is



    :LOOP
    TASKLIST | FIND /I "%filename%" >NUL 2>&1
    IF ERRORLEVEL 1 (
    GOTO CONTINUE
    )
    ECHO %filename% is still running
    PING -n 6 127.0.0.1>NUL
    GOTO LOOP


    Alternatively, you could swap the test around and avoid the goto CONTINUE altogether.



    :LOOP
    TASKLIST | FIND /I "%filename%" >NUL 2>&1
    IF ERRORLEVEL 0 (
    ECHO %filename% is still running
    PING -n 6 127.0.0.1>NUL
    GOTO LOOP
    )


    I would personally find that easier to read as the batch magic equivalent of a conventional spin lock style construction.







    share|improve this answer















    share|improve this answer



    share|improve this answer








    edited May 2 at 19:33


























    answered May 2 at 19:14









    Josiah

    3,172326




    3,172326











    • Ah yes, I like your loop better. I had taken most of that "wait" code from another post.
      – Kyle Delaney
      May 2 at 20:04
















    • Ah yes, I like your loop better. I had taken most of that "wait" code from another post.
      – Kyle Delaney
      May 2 at 20:04















    Ah yes, I like your loop better. I had taken most of that "wait" code from another post.
    – Kyle Delaney
    May 2 at 20:04




    Ah yes, I like your loop better. I had taken most of that "wait" code from another post.
    – Kyle Delaney
    May 2 at 20:04












    up vote
    1
    down vote













    I've applied Josiah's suggestions.



    I added a kill switch rather than removing the TASKKILL because there are cases where an application runs a batch file and waits for it to exit so the application wouldn't just end on its own. For example, in NSIS I'm using nsExec::Exec to run the batch file silently.



    As for the idea about the calling program inserting its path into the batch file
    directly, I'll leave that up to whoever writes the calling program. The current parameter implementation can serve as placeholders for that. But note that if the first parameter is omitted the kill switch won't work in the current design, so if direct placement is implemented then the kill switch should be changed as well.



    @ECHO OFF

    rem // This is needed for GOTO:EOF or EXIT /B
    SETLOCAL EnableExtensions

    rem // Pull out the name/extension from the path provided in the first parameter
    rem // Ex: C:Folderfile.exe becomes file.exe
    SET filename=%~nx1

    rem // Exit if no parameter is provided
    IF "%filename%"=="" EXIT /B

    rem // Kill the task if second parameter is /kill (case-insensitive)
    IF /I "%~2"=="/kill" TASKKILL /IM "%filename%" /F

    :LOOP

    rem // See if TASKLIST result contains the filename, while suppressing output
    TASKLIST | FIND /I "%filename%" >NUL 2>&1

    rem // %ERRORLEVEL% will be zero if the filename was found
    IF ERRORLEVEL 0 (
    ECHO %filename% is still running

    rem // Wait for 5 seconds
    PING -n 6 127.0.0.1>NUL

    GOTO LOOP
    )

    rem // "%~f1" expands to the full path provided in the first parameter
    DEL /F "%~f1"

    rem // Delete this batch file
    DEL /F "%~f0"





    share|improve this answer

























      up vote
      1
      down vote













      I've applied Josiah's suggestions.



      I added a kill switch rather than removing the TASKKILL because there are cases where an application runs a batch file and waits for it to exit so the application wouldn't just end on its own. For example, in NSIS I'm using nsExec::Exec to run the batch file silently.



      As for the idea about the calling program inserting its path into the batch file
      directly, I'll leave that up to whoever writes the calling program. The current parameter implementation can serve as placeholders for that. But note that if the first parameter is omitted the kill switch won't work in the current design, so if direct placement is implemented then the kill switch should be changed as well.



      @ECHO OFF

      rem // This is needed for GOTO:EOF or EXIT /B
      SETLOCAL EnableExtensions

      rem // Pull out the name/extension from the path provided in the first parameter
      rem // Ex: C:Folderfile.exe becomes file.exe
      SET filename=%~nx1

      rem // Exit if no parameter is provided
      IF "%filename%"=="" EXIT /B

      rem // Kill the task if second parameter is /kill (case-insensitive)
      IF /I "%~2"=="/kill" TASKKILL /IM "%filename%" /F

      :LOOP

      rem // See if TASKLIST result contains the filename, while suppressing output
      TASKLIST | FIND /I "%filename%" >NUL 2>&1

      rem // %ERRORLEVEL% will be zero if the filename was found
      IF ERRORLEVEL 0 (
      ECHO %filename% is still running

      rem // Wait for 5 seconds
      PING -n 6 127.0.0.1>NUL

      GOTO LOOP
      )

      rem // "%~f1" expands to the full path provided in the first parameter
      DEL /F "%~f1"

      rem // Delete this batch file
      DEL /F "%~f0"





      share|improve this answer























        up vote
        1
        down vote










        up vote
        1
        down vote









        I've applied Josiah's suggestions.



        I added a kill switch rather than removing the TASKKILL because there are cases where an application runs a batch file and waits for it to exit so the application wouldn't just end on its own. For example, in NSIS I'm using nsExec::Exec to run the batch file silently.



        As for the idea about the calling program inserting its path into the batch file
        directly, I'll leave that up to whoever writes the calling program. The current parameter implementation can serve as placeholders for that. But note that if the first parameter is omitted the kill switch won't work in the current design, so if direct placement is implemented then the kill switch should be changed as well.



        @ECHO OFF

        rem // This is needed for GOTO:EOF or EXIT /B
        SETLOCAL EnableExtensions

        rem // Pull out the name/extension from the path provided in the first parameter
        rem // Ex: C:Folderfile.exe becomes file.exe
        SET filename=%~nx1

        rem // Exit if no parameter is provided
        IF "%filename%"=="" EXIT /B

        rem // Kill the task if second parameter is /kill (case-insensitive)
        IF /I "%~2"=="/kill" TASKKILL /IM "%filename%" /F

        :LOOP

        rem // See if TASKLIST result contains the filename, while suppressing output
        TASKLIST | FIND /I "%filename%" >NUL 2>&1

        rem // %ERRORLEVEL% will be zero if the filename was found
        IF ERRORLEVEL 0 (
        ECHO %filename% is still running

        rem // Wait for 5 seconds
        PING -n 6 127.0.0.1>NUL

        GOTO LOOP
        )

        rem // "%~f1" expands to the full path provided in the first parameter
        DEL /F "%~f1"

        rem // Delete this batch file
        DEL /F "%~f0"





        share|improve this answer













        I've applied Josiah's suggestions.



        I added a kill switch rather than removing the TASKKILL because there are cases where an application runs a batch file and waits for it to exit so the application wouldn't just end on its own. For example, in NSIS I'm using nsExec::Exec to run the batch file silently.



        As for the idea about the calling program inserting its path into the batch file
        directly, I'll leave that up to whoever writes the calling program. The current parameter implementation can serve as placeholders for that. But note that if the first parameter is omitted the kill switch won't work in the current design, so if direct placement is implemented then the kill switch should be changed as well.



        @ECHO OFF

        rem // This is needed for GOTO:EOF or EXIT /B
        SETLOCAL EnableExtensions

        rem // Pull out the name/extension from the path provided in the first parameter
        rem // Ex: C:Folderfile.exe becomes file.exe
        SET filename=%~nx1

        rem // Exit if no parameter is provided
        IF "%filename%"=="" EXIT /B

        rem // Kill the task if second parameter is /kill (case-insensitive)
        IF /I "%~2"=="/kill" TASKKILL /IM "%filename%" /F

        :LOOP

        rem // See if TASKLIST result contains the filename, while suppressing output
        TASKLIST | FIND /I "%filename%" >NUL 2>&1

        rem // %ERRORLEVEL% will be zero if the filename was found
        IF ERRORLEVEL 0 (
        ECHO %filename% is still running

        rem // Wait for 5 seconds
        PING -n 6 127.0.0.1>NUL

        GOTO LOOP
        )

        rem // "%~f1" expands to the full path provided in the first parameter
        DEL /F "%~f1"

        rem // Delete this batch file
        DEL /F "%~f0"






        share|improve this answer













        share|improve this answer



        share|improve this answer











        answered May 4 at 21:08









        Kyle Delaney

        1636




        1636






















             

            draft saved


            draft discarded


























             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f193486%2fbatch-file-to-delete-calling-program-and-then-itself%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            Python Lists

            Aion

            JavaScript Array Iteration Methods