-2

I created a cmd process in which I display the output to a window. I would like to be able to terminate the command like pressing Control-c in the command prompt.

new ProcessStartInfo("cmd.exe");

The only option I can think of is to terminate the process. Is this what pressing control-c does? The problem with this is some user settings will be lost. Two I can think of are prompt and the current directory. could there be any others? I can remember these and create a new process and reset them. Or is there another way to simulate the interruption?

enter image description here

You can start a process by calling the Start method. You can also end the process by calling the Kill method. All well and good. Now lets start a process by running cmd.exe and redirecting the input and output. So now assume we execute a command that takes a long time. It would be nice to cancel the command like we can do in a DOS window (Command Prompt) instead of forcing the user to close and reopen the app losing their history in the process.

I can provide more details if necessary.

OldProgrammer
  • 12,050
  • 4
  • 24
  • 45
Lost Man
  • 1
  • 1
  • 3
  • 1
    CTRL+C in your cmd.exe, after starting a process from it - will kill (more like butcher) the process. you can do the same by invoking "taskkill /im ". – Stavm Feb 05 '17 at 15:58
  • actually ctrl-c doesn't do anything. cmd.exe IS the process. That process executes a command. I wish to terminate the command without killing the process. Is this possible? – Lost Man Feb 05 '17 at 16:28
  • From one hand the new process you create is just to display an output. On the other hand, you need to save "some user settings". It's not clear. – elirandav Feb 05 '17 at 16:34
  • Actually the window is to display the output, the process accepts commands and returns the output. Think of the command prompt except instead of everything in one window the input and output are redirected. I will post a screenshot – Lost Man Feb 05 '17 at 16:54
  • Possible duplicate, I think already answered here [http://stackoverflow.com/questions/24796722/how-to-close-a-cmd-window-after-i-ran-an-exe-file-from-it](http://stackoverflow.com/questions/24796722/how-to-close-a-cmd-window-after-i-ran-an-exe-file-from-it) – Vepa Durdiyev Feb 05 '17 at 17:02
  • @Vepa, Not a duplicate at all. I wish to terminate the command, not the process. It is really easy to terminate the process. You can call the kill method of the process or enter the "Exit" command. Both work. I will expand the description to try to be more clear. – Lost Man Feb 05 '17 at 17:16
  • 2
    The commands you run on `cmd` ARE process themselves, they are no magic (except the builtins, like `dir`). You can kill them separately... – This company is turning evil. Feb 05 '17 at 17:27
  • @Satvm: No, `cmd.exe` does not terminate its child when Ctrl+C is pressed. It triggers the console control+C handler via `GenerateConsoleCtrlEvent`, and you can't do that from outside the console process group. – Ben Voigt Feb 05 '17 at 17:32
  • How do I kill dir? That is actually the command that brought this issue to the fore front. Say someone issues dir /s from the root of a large hard drive? The only way to stop it is close the app and re-open it. Not the best option. – Lost Man Feb 05 '17 at 17:32
  • cmd.exe is the windows commandline interpreter. commands like "dir" are built in to the process. you have to kill cmd.exe, as other have stated. – OldProgrammer Feb 05 '17 at 17:34
  • @OldProgrammer: It's possible to interrupt a builtin command without killing the cmd.exe process. – Ben Voigt Feb 05 '17 at 17:41
  • @LostMan Can't write comment, thus writing an answer, not sure if you visited link I provide, but title from that link literally says how to close "cmd" window, same as you, cmd is also a process. Just try solution provided on that link first. – Vepa Durdiyev Feb 05 '17 at 17:30

1 Answers1

1

The mechanism that cmd.exe uses1 is GenerateConsoleCtrlEvent, and it is not available when your Process.Start call created a new console, because of this restriction in the documentation:

Only those processes in the group that share the same console as the calling process receive the signal. In other words, if a process in the group creates a new console, that process does not receive the signal, nor do its descendants.

The option you have is to not launch cmd.exe directly, but start a console program that is in turn responsible both for starting cmd.exe in its shared console, and also keeping a communication link with your program open in order to know when to generate console control events.


Actually it should be the console subsystem detecting Ctrl+C and generating the console event, and it's received by both cmd.exe and any child process. cmd.exe has a complex handler that will cancel a running builtin command (like dir) and not exit. Child processes may also have logic to exit cleanly and save state when the console control eventis seen.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • Thanks Ben for the explanation. However as a solution it is unclear. I can create a process using process.Start but you said that it won't work. There's also a worker thread but I suspect that it will not work either. Can you provide an example on what you are suggesting? – Lost Man Feb 05 '17 at 18:16
  • @LostMan: In your particular situation, when you're redirecting input and output, it may be entirely impossible to use console control events. When you launch `cmd.exe` normally, its input and output will be a console object, and there are two important cases -- if the parent process is a console application, cmd.exe will launch using the same console, and the parent process can send console control events. If the parent process doesn't have a console, `cmd.exe` will get a brand new one, not shared with the parent. So my workaround is to launch cmd.exe from a process that does have a console – Ben Voigt Feb 05 '17 at 18:20
  • I can create a console application as a wrapper and have that start cmd,exe. It would be trivial to pass data back and from from the wrapper to a windows form application. So are you saying if I should raise the event on the parent console app? – Lost Man Feb 05 '17 at 18:40
  • @LostMan: Yes, it's definitely worth a try. – Ben Voigt Feb 05 '17 at 18:42