Batch script calling robocopy in Process won't terminate









up vote
1
down vote

favorite
1












If process.Kill() is called from another thread or even another program, the process never comes out of WaitForExit() if the batch script used robocopy.exe until it is finished as if it wasn't killed.



Robocopy.exe is called from the batch script. Every other script or program ends as you'd expect.



 ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "batch.bat";
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardOutput = true;
startInfo.OutputDataReceived += CaptureHandler;
startInfo.RedirectStandardError = true;
startInfo.ErrorDataReceived += CaptureHandler;
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();


The batch script looks like:



@echo off
call "robocopy.exe" "somedir" "somedest" /mir /fp /ndl /njh /njs /ns


I have a feeling it has to do with the output handlers.
I tried using process.CancelErrorRead and process.CancelOutputRead() as well after the Kill() call and before, no luck.



Oddly, if you use process.WaitForExit(timeout) overload, it will return true immediately after Kill() from the other thread. However, it's lying. The process is still running! If you try process.WaitForExit() again, as per the MSDN doc, it will still wait for the process to finish despite HasExited saying true.




To ensure that asynchronous event handling has been completed, call the WaitForExit() overload that takes no parameter after receiving a true from this overload.




https://msdn.microsoft.com/en-us/library/ty0d8k56(v=vs.110).aspx










share|improve this question





















  • You could just try process.Close() at the end, or if you don't need to redirect output & error (in case robocopy.exe handles it) you could simply use System.Diagnostics.Process.Start(@"c:batch.bat"); (correct the path as required) as it will just open the batch file and quit the process.
    – Keyur PATEL
    Jun 23 '17 at 3:21










  • Close also doesn't work. And I need to wait on it.
    – user99999991
    Jun 23 '17 at 16:18














up vote
1
down vote

favorite
1












If process.Kill() is called from another thread or even another program, the process never comes out of WaitForExit() if the batch script used robocopy.exe until it is finished as if it wasn't killed.



Robocopy.exe is called from the batch script. Every other script or program ends as you'd expect.



 ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "batch.bat";
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardOutput = true;
startInfo.OutputDataReceived += CaptureHandler;
startInfo.RedirectStandardError = true;
startInfo.ErrorDataReceived += CaptureHandler;
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();


The batch script looks like:



@echo off
call "robocopy.exe" "somedir" "somedest" /mir /fp /ndl /njh /njs /ns


I have a feeling it has to do with the output handlers.
I tried using process.CancelErrorRead and process.CancelOutputRead() as well after the Kill() call and before, no luck.



Oddly, if you use process.WaitForExit(timeout) overload, it will return true immediately after Kill() from the other thread. However, it's lying. The process is still running! If you try process.WaitForExit() again, as per the MSDN doc, it will still wait for the process to finish despite HasExited saying true.




To ensure that asynchronous event handling has been completed, call the WaitForExit() overload that takes no parameter after receiving a true from this overload.




https://msdn.microsoft.com/en-us/library/ty0d8k56(v=vs.110).aspx










share|improve this question





















  • You could just try process.Close() at the end, or if you don't need to redirect output & error (in case robocopy.exe handles it) you could simply use System.Diagnostics.Process.Start(@"c:batch.bat"); (correct the path as required) as it will just open the batch file and quit the process.
    – Keyur PATEL
    Jun 23 '17 at 3:21










  • Close also doesn't work. And I need to wait on it.
    – user99999991
    Jun 23 '17 at 16:18












up vote
1
down vote

favorite
1









up vote
1
down vote

favorite
1






1





If process.Kill() is called from another thread or even another program, the process never comes out of WaitForExit() if the batch script used robocopy.exe until it is finished as if it wasn't killed.



Robocopy.exe is called from the batch script. Every other script or program ends as you'd expect.



 ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "batch.bat";
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardOutput = true;
startInfo.OutputDataReceived += CaptureHandler;
startInfo.RedirectStandardError = true;
startInfo.ErrorDataReceived += CaptureHandler;
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();


The batch script looks like:



@echo off
call "robocopy.exe" "somedir" "somedest" /mir /fp /ndl /njh /njs /ns


I have a feeling it has to do with the output handlers.
I tried using process.CancelErrorRead and process.CancelOutputRead() as well after the Kill() call and before, no luck.



Oddly, if you use process.WaitForExit(timeout) overload, it will return true immediately after Kill() from the other thread. However, it's lying. The process is still running! If you try process.WaitForExit() again, as per the MSDN doc, it will still wait for the process to finish despite HasExited saying true.




To ensure that asynchronous event handling has been completed, call the WaitForExit() overload that takes no parameter after receiving a true from this overload.




https://msdn.microsoft.com/en-us/library/ty0d8k56(v=vs.110).aspx










share|improve this question













If process.Kill() is called from another thread or even another program, the process never comes out of WaitForExit() if the batch script used robocopy.exe until it is finished as if it wasn't killed.



Robocopy.exe is called from the batch script. Every other script or program ends as you'd expect.



 ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "batch.bat";
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardOutput = true;
startInfo.OutputDataReceived += CaptureHandler;
startInfo.RedirectStandardError = true;
startInfo.ErrorDataReceived += CaptureHandler;
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();


The batch script looks like:



@echo off
call "robocopy.exe" "somedir" "somedest" /mir /fp /ndl /njh /njs /ns


I have a feeling it has to do with the output handlers.
I tried using process.CancelErrorRead and process.CancelOutputRead() as well after the Kill() call and before, no luck.



Oddly, if you use process.WaitForExit(timeout) overload, it will return true immediately after Kill() from the other thread. However, it's lying. The process is still running! If you try process.WaitForExit() again, as per the MSDN doc, it will still wait for the process to finish despite HasExited saying true.




To ensure that asynchronous event handling has been completed, call the WaitForExit() overload that takes no parameter after receiving a true from this overload.




https://msdn.microsoft.com/en-us/library/ty0d8k56(v=vs.110).aspx







c# .net windows batch-file robocopy






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jun 23 '17 at 2:58









user99999991

57121128




57121128











  • You could just try process.Close() at the end, or if you don't need to redirect output & error (in case robocopy.exe handles it) you could simply use System.Diagnostics.Process.Start(@"c:batch.bat"); (correct the path as required) as it will just open the batch file and quit the process.
    – Keyur PATEL
    Jun 23 '17 at 3:21










  • Close also doesn't work. And I need to wait on it.
    – user99999991
    Jun 23 '17 at 16:18
















  • You could just try process.Close() at the end, or if you don't need to redirect output & error (in case robocopy.exe handles it) you could simply use System.Diagnostics.Process.Start(@"c:batch.bat"); (correct the path as required) as it will just open the batch file and quit the process.
    – Keyur PATEL
    Jun 23 '17 at 3:21










  • Close also doesn't work. And I need to wait on it.
    – user99999991
    Jun 23 '17 at 16:18















You could just try process.Close() at the end, or if you don't need to redirect output & error (in case robocopy.exe handles it) you could simply use System.Diagnostics.Process.Start(@"c:batch.bat"); (correct the path as required) as it will just open the batch file and quit the process.
– Keyur PATEL
Jun 23 '17 at 3:21




You could just try process.Close() at the end, or if you don't need to redirect output & error (in case robocopy.exe handles it) you could simply use System.Diagnostics.Process.Start(@"c:batch.bat"); (correct the path as required) as it will just open the batch file and quit the process.
– Keyur PATEL
Jun 23 '17 at 3:21












Close also doesn't work. And I need to wait on it.
– user99999991
Jun 23 '17 at 16:18




Close also doesn't work. And I need to wait on it.
– user99999991
Jun 23 '17 at 16:18












4 Answers
4






active

oldest

votes

















up vote
2
down vote



accepted










You are successfully killing the batch processor (cmd.exe) but doing so won't kill robocopy, which is a separate process.



It doesn't seem to be documented, but when we look at the .NET source code it turns out that the Process.WaitForExit() method doesn't just wait for the process to exit, it also waits for end-of-file on the standard output and standard error streams. In this scenario, that means that it waits for robocopy to finish even after the batch processor has been killed.



(The overload of Process.WaitForExit with a timeout does not have this extra logic.)



I think this constitutes a bug in the .NET framework. At the very least, it should be documented.



As a workaround, you can use .HasExited and/or the version of WaitForExit with a timeout to determine whether the process has exited or not. Of course, in your scenario you might prefer to wait for grandchild processes, in which case your code is already behaving as desired.






share|improve this answer




















  • So is there anyway to kill robocopy from the application without it knowing that robocopy is being used? The application shouldn't have to know that the batch script is launching another process, I would expect kill to nail all child processes. I guess maybe I could traverse the child trees first and kill it off bottom to top?
    – user99999991
    Jun 23 '17 at 16:20










  • Not trivially; by default, Windows doesn't track that information. The most robust approach is to launch the batch script inside a job although I don't know whether .NET has support for that, you might have to P/Invoke. A messier but simpler option is to start it in a separate console with a unique title, and kill all the processes belonging to that console.
    – Harry Johnston
    Jun 23 '17 at 23:46










  • The application shouldn't have to know that the batch script is launching another process - Windows isn't really designed for this sort of approach; launching a batch script to do work on your behalf is very UNIX-y. You can do it, of course, Windows just doesn't go out of its way to make it easy.
    – Harry Johnston
    Jun 23 '17 at 23:59

















up vote
1
down vote













I ran into the same problem. In my case, dropping the /mt switch from the RoboCopy argument list seemed to fix the issue.






share|improve this answer





























    up vote
    1
    down vote













    Having followed up on Harry Johnston's helpful answer, I found that the process completes normally when you avoid RedirectStandardOutput = true. If this isn't an acceptable solution I found that using robocopy's /LOG:"C:logsrobocopy.txt" switch to send its standard output to an external log file also works (although you lose the ability to get the file/directory log output from the process object itself).






    share|improve this answer





























      up vote
      0
      down vote













      Looks like right now the only way to do this without the application knowing to terminate Robocopy.exe specifically is to do kill the children of the script process before killing the script itself:



      Kill process tree programmatically in C#



       /// <summary>
      /// Kill a process, and all of its children, grandchildren, etc.
      /// </summary>
      /// <param name="pid">Process ID.</param>
      private static void KillProcessAndChildren(int pid)

      ManagementObjectSearcher searcher = new ManagementObjectSearcher
      ("Select * From Win32_Process Where ParentProcessID=" + pid);
      ManagementObjectCollection moc = searcher.Get();
      foreach (ManagementObject mo in moc)

      KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"]));

      try

      Process proc = Process.GetProcessById(pid);
      proc.Kill();

      catch (ArgumentException)

      // Process already exited.







      share|improve this answer




















      • That's a dangerous approach; it might kill unrelated processes. This answer is better.
        – Harry Johnston
        Jun 23 '17 at 23:49










      Your Answer






      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: "1"
      ;
      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: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













       

      draft saved


      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f44712364%2fbatch-script-calling-robocopy-in-process-wont-terminate%23new-answer', 'question_page');

      );

      Post as a guest






























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      2
      down vote



      accepted










      You are successfully killing the batch processor (cmd.exe) but doing so won't kill robocopy, which is a separate process.



      It doesn't seem to be documented, but when we look at the .NET source code it turns out that the Process.WaitForExit() method doesn't just wait for the process to exit, it also waits for end-of-file on the standard output and standard error streams. In this scenario, that means that it waits for robocopy to finish even after the batch processor has been killed.



      (The overload of Process.WaitForExit with a timeout does not have this extra logic.)



      I think this constitutes a bug in the .NET framework. At the very least, it should be documented.



      As a workaround, you can use .HasExited and/or the version of WaitForExit with a timeout to determine whether the process has exited or not. Of course, in your scenario you might prefer to wait for grandchild processes, in which case your code is already behaving as desired.






      share|improve this answer




















      • So is there anyway to kill robocopy from the application without it knowing that robocopy is being used? The application shouldn't have to know that the batch script is launching another process, I would expect kill to nail all child processes. I guess maybe I could traverse the child trees first and kill it off bottom to top?
        – user99999991
        Jun 23 '17 at 16:20










      • Not trivially; by default, Windows doesn't track that information. The most robust approach is to launch the batch script inside a job although I don't know whether .NET has support for that, you might have to P/Invoke. A messier but simpler option is to start it in a separate console with a unique title, and kill all the processes belonging to that console.
        – Harry Johnston
        Jun 23 '17 at 23:46










      • The application shouldn't have to know that the batch script is launching another process - Windows isn't really designed for this sort of approach; launching a batch script to do work on your behalf is very UNIX-y. You can do it, of course, Windows just doesn't go out of its way to make it easy.
        – Harry Johnston
        Jun 23 '17 at 23:59














      up vote
      2
      down vote



      accepted










      You are successfully killing the batch processor (cmd.exe) but doing so won't kill robocopy, which is a separate process.



      It doesn't seem to be documented, but when we look at the .NET source code it turns out that the Process.WaitForExit() method doesn't just wait for the process to exit, it also waits for end-of-file on the standard output and standard error streams. In this scenario, that means that it waits for robocopy to finish even after the batch processor has been killed.



      (The overload of Process.WaitForExit with a timeout does not have this extra logic.)



      I think this constitutes a bug in the .NET framework. At the very least, it should be documented.



      As a workaround, you can use .HasExited and/or the version of WaitForExit with a timeout to determine whether the process has exited or not. Of course, in your scenario you might prefer to wait for grandchild processes, in which case your code is already behaving as desired.






      share|improve this answer




















      • So is there anyway to kill robocopy from the application without it knowing that robocopy is being used? The application shouldn't have to know that the batch script is launching another process, I would expect kill to nail all child processes. I guess maybe I could traverse the child trees first and kill it off bottom to top?
        – user99999991
        Jun 23 '17 at 16:20










      • Not trivially; by default, Windows doesn't track that information. The most robust approach is to launch the batch script inside a job although I don't know whether .NET has support for that, you might have to P/Invoke. A messier but simpler option is to start it in a separate console with a unique title, and kill all the processes belonging to that console.
        – Harry Johnston
        Jun 23 '17 at 23:46










      • The application shouldn't have to know that the batch script is launching another process - Windows isn't really designed for this sort of approach; launching a batch script to do work on your behalf is very UNIX-y. You can do it, of course, Windows just doesn't go out of its way to make it easy.
        – Harry Johnston
        Jun 23 '17 at 23:59












      up vote
      2
      down vote



      accepted







      up vote
      2
      down vote



      accepted






      You are successfully killing the batch processor (cmd.exe) but doing so won't kill robocopy, which is a separate process.



      It doesn't seem to be documented, but when we look at the .NET source code it turns out that the Process.WaitForExit() method doesn't just wait for the process to exit, it also waits for end-of-file on the standard output and standard error streams. In this scenario, that means that it waits for robocopy to finish even after the batch processor has been killed.



      (The overload of Process.WaitForExit with a timeout does not have this extra logic.)



      I think this constitutes a bug in the .NET framework. At the very least, it should be documented.



      As a workaround, you can use .HasExited and/or the version of WaitForExit with a timeout to determine whether the process has exited or not. Of course, in your scenario you might prefer to wait for grandchild processes, in which case your code is already behaving as desired.






      share|improve this answer












      You are successfully killing the batch processor (cmd.exe) but doing so won't kill robocopy, which is a separate process.



      It doesn't seem to be documented, but when we look at the .NET source code it turns out that the Process.WaitForExit() method doesn't just wait for the process to exit, it also waits for end-of-file on the standard output and standard error streams. In this scenario, that means that it waits for robocopy to finish even after the batch processor has been killed.



      (The overload of Process.WaitForExit with a timeout does not have this extra logic.)



      I think this constitutes a bug in the .NET framework. At the very least, it should be documented.



      As a workaround, you can use .HasExited and/or the version of WaitForExit with a timeout to determine whether the process has exited or not. Of course, in your scenario you might prefer to wait for grandchild processes, in which case your code is already behaving as desired.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Jun 23 '17 at 4:05









      Harry Johnston

      30k541107




      30k541107











      • So is there anyway to kill robocopy from the application without it knowing that robocopy is being used? The application shouldn't have to know that the batch script is launching another process, I would expect kill to nail all child processes. I guess maybe I could traverse the child trees first and kill it off bottom to top?
        – user99999991
        Jun 23 '17 at 16:20










      • Not trivially; by default, Windows doesn't track that information. The most robust approach is to launch the batch script inside a job although I don't know whether .NET has support for that, you might have to P/Invoke. A messier but simpler option is to start it in a separate console with a unique title, and kill all the processes belonging to that console.
        – Harry Johnston
        Jun 23 '17 at 23:46










      • The application shouldn't have to know that the batch script is launching another process - Windows isn't really designed for this sort of approach; launching a batch script to do work on your behalf is very UNIX-y. You can do it, of course, Windows just doesn't go out of its way to make it easy.
        – Harry Johnston
        Jun 23 '17 at 23:59
















      • So is there anyway to kill robocopy from the application without it knowing that robocopy is being used? The application shouldn't have to know that the batch script is launching another process, I would expect kill to nail all child processes. I guess maybe I could traverse the child trees first and kill it off bottom to top?
        – user99999991
        Jun 23 '17 at 16:20










      • Not trivially; by default, Windows doesn't track that information. The most robust approach is to launch the batch script inside a job although I don't know whether .NET has support for that, you might have to P/Invoke. A messier but simpler option is to start it in a separate console with a unique title, and kill all the processes belonging to that console.
        – Harry Johnston
        Jun 23 '17 at 23:46










      • The application shouldn't have to know that the batch script is launching another process - Windows isn't really designed for this sort of approach; launching a batch script to do work on your behalf is very UNIX-y. You can do it, of course, Windows just doesn't go out of its way to make it easy.
        – Harry Johnston
        Jun 23 '17 at 23:59















      So is there anyway to kill robocopy from the application without it knowing that robocopy is being used? The application shouldn't have to know that the batch script is launching another process, I would expect kill to nail all child processes. I guess maybe I could traverse the child trees first and kill it off bottom to top?
      – user99999991
      Jun 23 '17 at 16:20




      So is there anyway to kill robocopy from the application without it knowing that robocopy is being used? The application shouldn't have to know that the batch script is launching another process, I would expect kill to nail all child processes. I guess maybe I could traverse the child trees first and kill it off bottom to top?
      – user99999991
      Jun 23 '17 at 16:20












      Not trivially; by default, Windows doesn't track that information. The most robust approach is to launch the batch script inside a job although I don't know whether .NET has support for that, you might have to P/Invoke. A messier but simpler option is to start it in a separate console with a unique title, and kill all the processes belonging to that console.
      – Harry Johnston
      Jun 23 '17 at 23:46




      Not trivially; by default, Windows doesn't track that information. The most robust approach is to launch the batch script inside a job although I don't know whether .NET has support for that, you might have to P/Invoke. A messier but simpler option is to start it in a separate console with a unique title, and kill all the processes belonging to that console.
      – Harry Johnston
      Jun 23 '17 at 23:46












      The application shouldn't have to know that the batch script is launching another process - Windows isn't really designed for this sort of approach; launching a batch script to do work on your behalf is very UNIX-y. You can do it, of course, Windows just doesn't go out of its way to make it easy.
      – Harry Johnston
      Jun 23 '17 at 23:59




      The application shouldn't have to know that the batch script is launching another process - Windows isn't really designed for this sort of approach; launching a batch script to do work on your behalf is very UNIX-y. You can do it, of course, Windows just doesn't go out of its way to make it easy.
      – Harry Johnston
      Jun 23 '17 at 23:59












      up vote
      1
      down vote













      I ran into the same problem. In my case, dropping the /mt switch from the RoboCopy argument list seemed to fix the issue.






      share|improve this answer


























        up vote
        1
        down vote













        I ran into the same problem. In my case, dropping the /mt switch from the RoboCopy argument list seemed to fix the issue.






        share|improve this answer
























          up vote
          1
          down vote










          up vote
          1
          down vote









          I ran into the same problem. In my case, dropping the /mt switch from the RoboCopy argument list seemed to fix the issue.






          share|improve this answer














          I ran into the same problem. In my case, dropping the /mt switch from the RoboCopy argument list seemed to fix the issue.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Apr 16 at 19:25









          SherylHohman

          4,11963145




          4,11963145










          answered Apr 16 at 19:07









          Joe M

          111




          111




















              up vote
              1
              down vote













              Having followed up on Harry Johnston's helpful answer, I found that the process completes normally when you avoid RedirectStandardOutput = true. If this isn't an acceptable solution I found that using robocopy's /LOG:"C:logsrobocopy.txt" switch to send its standard output to an external log file also works (although you lose the ability to get the file/directory log output from the process object itself).






              share|improve this answer


























                up vote
                1
                down vote













                Having followed up on Harry Johnston's helpful answer, I found that the process completes normally when you avoid RedirectStandardOutput = true. If this isn't an acceptable solution I found that using robocopy's /LOG:"C:logsrobocopy.txt" switch to send its standard output to an external log file also works (although you lose the ability to get the file/directory log output from the process object itself).






                share|improve this answer
























                  up vote
                  1
                  down vote










                  up vote
                  1
                  down vote









                  Having followed up on Harry Johnston's helpful answer, I found that the process completes normally when you avoid RedirectStandardOutput = true. If this isn't an acceptable solution I found that using robocopy's /LOG:"C:logsrobocopy.txt" switch to send its standard output to an external log file also works (although you lose the ability to get the file/directory log output from the process object itself).






                  share|improve this answer














                  Having followed up on Harry Johnston's helpful answer, I found that the process completes normally when you avoid RedirectStandardOutput = true. If this isn't an acceptable solution I found that using robocopy's /LOG:"C:logsrobocopy.txt" switch to send its standard output to an external log file also works (although you lose the ability to get the file/directory log output from the process object itself).







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 2 days ago

























                  answered 2 days ago









                  rogersillito

                  5341621




                  5341621




















                      up vote
                      0
                      down vote













                      Looks like right now the only way to do this without the application knowing to terminate Robocopy.exe specifically is to do kill the children of the script process before killing the script itself:



                      Kill process tree programmatically in C#



                       /// <summary>
                      /// Kill a process, and all of its children, grandchildren, etc.
                      /// </summary>
                      /// <param name="pid">Process ID.</param>
                      private static void KillProcessAndChildren(int pid)

                      ManagementObjectSearcher searcher = new ManagementObjectSearcher
                      ("Select * From Win32_Process Where ParentProcessID=" + pid);
                      ManagementObjectCollection moc = searcher.Get();
                      foreach (ManagementObject mo in moc)

                      KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"]));

                      try

                      Process proc = Process.GetProcessById(pid);
                      proc.Kill();

                      catch (ArgumentException)

                      // Process already exited.







                      share|improve this answer




















                      • That's a dangerous approach; it might kill unrelated processes. This answer is better.
                        – Harry Johnston
                        Jun 23 '17 at 23:49














                      up vote
                      0
                      down vote













                      Looks like right now the only way to do this without the application knowing to terminate Robocopy.exe specifically is to do kill the children of the script process before killing the script itself:



                      Kill process tree programmatically in C#



                       /// <summary>
                      /// Kill a process, and all of its children, grandchildren, etc.
                      /// </summary>
                      /// <param name="pid">Process ID.</param>
                      private static void KillProcessAndChildren(int pid)

                      ManagementObjectSearcher searcher = new ManagementObjectSearcher
                      ("Select * From Win32_Process Where ParentProcessID=" + pid);
                      ManagementObjectCollection moc = searcher.Get();
                      foreach (ManagementObject mo in moc)

                      KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"]));

                      try

                      Process proc = Process.GetProcessById(pid);
                      proc.Kill();

                      catch (ArgumentException)

                      // Process already exited.







                      share|improve this answer




















                      • That's a dangerous approach; it might kill unrelated processes. This answer is better.
                        – Harry Johnston
                        Jun 23 '17 at 23:49












                      up vote
                      0
                      down vote










                      up vote
                      0
                      down vote









                      Looks like right now the only way to do this without the application knowing to terminate Robocopy.exe specifically is to do kill the children of the script process before killing the script itself:



                      Kill process tree programmatically in C#



                       /// <summary>
                      /// Kill a process, and all of its children, grandchildren, etc.
                      /// </summary>
                      /// <param name="pid">Process ID.</param>
                      private static void KillProcessAndChildren(int pid)

                      ManagementObjectSearcher searcher = new ManagementObjectSearcher
                      ("Select * From Win32_Process Where ParentProcessID=" + pid);
                      ManagementObjectCollection moc = searcher.Get();
                      foreach (ManagementObject mo in moc)

                      KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"]));

                      try

                      Process proc = Process.GetProcessById(pid);
                      proc.Kill();

                      catch (ArgumentException)

                      // Process already exited.







                      share|improve this answer












                      Looks like right now the only way to do this without the application knowing to terminate Robocopy.exe specifically is to do kill the children of the script process before killing the script itself:



                      Kill process tree programmatically in C#



                       /// <summary>
                      /// Kill a process, and all of its children, grandchildren, etc.
                      /// </summary>
                      /// <param name="pid">Process ID.</param>
                      private static void KillProcessAndChildren(int pid)

                      ManagementObjectSearcher searcher = new ManagementObjectSearcher
                      ("Select * From Win32_Process Where ParentProcessID=" + pid);
                      ManagementObjectCollection moc = searcher.Get();
                      foreach (ManagementObject mo in moc)

                      KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"]));

                      try

                      Process proc = Process.GetProcessById(pid);
                      proc.Kill();

                      catch (ArgumentException)

                      // Process already exited.








                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Jun 23 '17 at 21:06









                      user99999991

                      57121128




                      57121128











                      • That's a dangerous approach; it might kill unrelated processes. This answer is better.
                        – Harry Johnston
                        Jun 23 '17 at 23:49
















                      • That's a dangerous approach; it might kill unrelated processes. This answer is better.
                        – Harry Johnston
                        Jun 23 '17 at 23:49















                      That's a dangerous approach; it might kill unrelated processes. This answer is better.
                      – Harry Johnston
                      Jun 23 '17 at 23:49




                      That's a dangerous approach; it might kill unrelated processes. This answer is better.
                      – Harry Johnston
                      Jun 23 '17 at 23:49

















                       

                      draft saved


                      draft discarded















































                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f44712364%2fbatch-script-calling-robocopy-in-process-wont-terminate%23new-answer', 'question_page');

                      );

                      Post as a guest














































































                      Popular posts from this blog

                      Kleinkühnau

                      Makov (Slowakei)

                      Deutsches Schauspielhaus