How to use TerminateProcess() to close a console window
My C++ application starts a .cmd file as a child process like this:
SHELLEXECUTEINFOA execInfo = {0};
execInfo.cbSize = sizeof(execInfo);
execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NOASYNC;
execInfo.lpVerb = "open";
execInfo.lpFile = "test.cmd";
execInfo.lpDirectory = "C:\some\directory";
execInfo.nShow = SW_SHOWNORMAL;
BOOL result = ShellExecuteExA(&execInfo);
The script test.cmd
runs a console-mode .NET application that runs a long time, and it looks similar to this:
@echo off
echo Starting a long task...
dotnet.exe runforhours.dll
When ShellExecuteExA()
returns in my C++ application, the process handle in execInfo.hProcess
is saved for later use. The idea was to use that process handle to shut down the child process (script + exe).
But when I try to shut it down, nothing seems to happen. The console window and the long-running .NET application both happily continue running. This is the call to TerminateProcess()
:
TerminateProcess(child_process_handle, 1);
CloseHandle(child_process_handle);
Should TerminateProcess()
be expected to work in this case? Is it perhaps because this is a console window that it isn't working?
c++ winapi console-application shellexecuteex
add a comment |
My C++ application starts a .cmd file as a child process like this:
SHELLEXECUTEINFOA execInfo = {0};
execInfo.cbSize = sizeof(execInfo);
execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NOASYNC;
execInfo.lpVerb = "open";
execInfo.lpFile = "test.cmd";
execInfo.lpDirectory = "C:\some\directory";
execInfo.nShow = SW_SHOWNORMAL;
BOOL result = ShellExecuteExA(&execInfo);
The script test.cmd
runs a console-mode .NET application that runs a long time, and it looks similar to this:
@echo off
echo Starting a long task...
dotnet.exe runforhours.dll
When ShellExecuteExA()
returns in my C++ application, the process handle in execInfo.hProcess
is saved for later use. The idea was to use that process handle to shut down the child process (script + exe).
But when I try to shut it down, nothing seems to happen. The console window and the long-running .NET application both happily continue running. This is the call to TerminateProcess()
:
TerminateProcess(child_process_handle, 1);
CloseHandle(child_process_handle);
Should TerminateProcess()
be expected to work in this case? Is it perhaps because this is a console window that it isn't working?
c++ winapi console-application shellexecuteex
1
Right now you're flying blind. CheckTerminateProcess
's return value when you call it. If you get a return of zero, it failed and you may get more information fromGetLastError
.
– user4581301
Nov 23 '18 at 22:12
1
Also worth notingTerminateProcess
requests shutdown and returns. The other process will shut down later. It might be a while later.
– user4581301
Nov 23 '18 at 22:13
Upvoted @RbMm, useCreateProcess
– Tony J
Nov 23 '18 at 22:25
2
you createcmd.exe
, it startconhost.exe
- you view theconhost.exe
window really. thencmd.exe
start you .NET application, which use the sameconhost.exe
. then you kill initialcmd.exe
. but this is invisible process - nothing seems to happen. theconhost.exe
exit only when no more process used it, but in your case it used by your .NET application - as result it not exit and command window still visible. you possible can create job (terminate all on close), useCreateProcess
in suspended state, assign it to job and resume.
– RbMm
Nov 23 '18 at 22:44
You at best terminate cmd.exe, not the program(s) that were started by the .cmd file. Like dotnet.exe. It is a console program, that helps, consider GenerateConsoleCtrlEvent().
– Hans Passant
Nov 23 '18 at 23:18
add a comment |
My C++ application starts a .cmd file as a child process like this:
SHELLEXECUTEINFOA execInfo = {0};
execInfo.cbSize = sizeof(execInfo);
execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NOASYNC;
execInfo.lpVerb = "open";
execInfo.lpFile = "test.cmd";
execInfo.lpDirectory = "C:\some\directory";
execInfo.nShow = SW_SHOWNORMAL;
BOOL result = ShellExecuteExA(&execInfo);
The script test.cmd
runs a console-mode .NET application that runs a long time, and it looks similar to this:
@echo off
echo Starting a long task...
dotnet.exe runforhours.dll
When ShellExecuteExA()
returns in my C++ application, the process handle in execInfo.hProcess
is saved for later use. The idea was to use that process handle to shut down the child process (script + exe).
But when I try to shut it down, nothing seems to happen. The console window and the long-running .NET application both happily continue running. This is the call to TerminateProcess()
:
TerminateProcess(child_process_handle, 1);
CloseHandle(child_process_handle);
Should TerminateProcess()
be expected to work in this case? Is it perhaps because this is a console window that it isn't working?
c++ winapi console-application shellexecuteex
My C++ application starts a .cmd file as a child process like this:
SHELLEXECUTEINFOA execInfo = {0};
execInfo.cbSize = sizeof(execInfo);
execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NOASYNC;
execInfo.lpVerb = "open";
execInfo.lpFile = "test.cmd";
execInfo.lpDirectory = "C:\some\directory";
execInfo.nShow = SW_SHOWNORMAL;
BOOL result = ShellExecuteExA(&execInfo);
The script test.cmd
runs a console-mode .NET application that runs a long time, and it looks similar to this:
@echo off
echo Starting a long task...
dotnet.exe runforhours.dll
When ShellExecuteExA()
returns in my C++ application, the process handle in execInfo.hProcess
is saved for later use. The idea was to use that process handle to shut down the child process (script + exe).
But when I try to shut it down, nothing seems to happen. The console window and the long-running .NET application both happily continue running. This is the call to TerminateProcess()
:
TerminateProcess(child_process_handle, 1);
CloseHandle(child_process_handle);
Should TerminateProcess()
be expected to work in this case? Is it perhaps because this is a console window that it isn't working?
c++ winapi console-application shellexecuteex
c++ winapi console-application shellexecuteex
asked Nov 23 '18 at 22:08
StéphaneStéphane
8,8601768100
8,8601768100
1
Right now you're flying blind. CheckTerminateProcess
's return value when you call it. If you get a return of zero, it failed and you may get more information fromGetLastError
.
– user4581301
Nov 23 '18 at 22:12
1
Also worth notingTerminateProcess
requests shutdown and returns. The other process will shut down later. It might be a while later.
– user4581301
Nov 23 '18 at 22:13
Upvoted @RbMm, useCreateProcess
– Tony J
Nov 23 '18 at 22:25
2
you createcmd.exe
, it startconhost.exe
- you view theconhost.exe
window really. thencmd.exe
start you .NET application, which use the sameconhost.exe
. then you kill initialcmd.exe
. but this is invisible process - nothing seems to happen. theconhost.exe
exit only when no more process used it, but in your case it used by your .NET application - as result it not exit and command window still visible. you possible can create job (terminate all on close), useCreateProcess
in suspended state, assign it to job and resume.
– RbMm
Nov 23 '18 at 22:44
You at best terminate cmd.exe, not the program(s) that were started by the .cmd file. Like dotnet.exe. It is a console program, that helps, consider GenerateConsoleCtrlEvent().
– Hans Passant
Nov 23 '18 at 23:18
add a comment |
1
Right now you're flying blind. CheckTerminateProcess
's return value when you call it. If you get a return of zero, it failed and you may get more information fromGetLastError
.
– user4581301
Nov 23 '18 at 22:12
1
Also worth notingTerminateProcess
requests shutdown and returns. The other process will shut down later. It might be a while later.
– user4581301
Nov 23 '18 at 22:13
Upvoted @RbMm, useCreateProcess
– Tony J
Nov 23 '18 at 22:25
2
you createcmd.exe
, it startconhost.exe
- you view theconhost.exe
window really. thencmd.exe
start you .NET application, which use the sameconhost.exe
. then you kill initialcmd.exe
. but this is invisible process - nothing seems to happen. theconhost.exe
exit only when no more process used it, but in your case it used by your .NET application - as result it not exit and command window still visible. you possible can create job (terminate all on close), useCreateProcess
in suspended state, assign it to job and resume.
– RbMm
Nov 23 '18 at 22:44
You at best terminate cmd.exe, not the program(s) that were started by the .cmd file. Like dotnet.exe. It is a console program, that helps, consider GenerateConsoleCtrlEvent().
– Hans Passant
Nov 23 '18 at 23:18
1
1
Right now you're flying blind. Check
TerminateProcess
's return value when you call it. If you get a return of zero, it failed and you may get more information from GetLastError
.– user4581301
Nov 23 '18 at 22:12
Right now you're flying blind. Check
TerminateProcess
's return value when you call it. If you get a return of zero, it failed and you may get more information from GetLastError
.– user4581301
Nov 23 '18 at 22:12
1
1
Also worth noting
TerminateProcess
requests shutdown and returns. The other process will shut down later. It might be a while later.– user4581301
Nov 23 '18 at 22:13
Also worth noting
TerminateProcess
requests shutdown and returns. The other process will shut down later. It might be a while later.– user4581301
Nov 23 '18 at 22:13
Upvoted @RbMm, use
CreateProcess
– Tony J
Nov 23 '18 at 22:25
Upvoted @RbMm, use
CreateProcess
– Tony J
Nov 23 '18 at 22:25
2
2
you create
cmd.exe
, it start conhost.exe
- you view the conhost.exe
window really. then cmd.exe
start you .NET application, which use the same conhost.exe
. then you kill initial cmd.exe
. but this is invisible process - nothing seems to happen. the conhost.exe
exit only when no more process used it, but in your case it used by your .NET application - as result it not exit and command window still visible. you possible can create job (terminate all on close), use CreateProcess
in suspended state, assign it to job and resume.– RbMm
Nov 23 '18 at 22:44
you create
cmd.exe
, it start conhost.exe
- you view the conhost.exe
window really. then cmd.exe
start you .NET application, which use the same conhost.exe
. then you kill initial cmd.exe
. but this is invisible process - nothing seems to happen. the conhost.exe
exit only when no more process used it, but in your case it used by your .NET application - as result it not exit and command window still visible. you possible can create job (terminate all on close), use CreateProcess
in suspended state, assign it to job and resume.– RbMm
Nov 23 '18 at 22:44
You at best terminate cmd.exe, not the program(s) that were started by the .cmd file. Like dotnet.exe. It is a console program, that helps, consider GenerateConsoleCtrlEvent().
– Hans Passant
Nov 23 '18 at 23:18
You at best terminate cmd.exe, not the program(s) that were started by the .cmd file. Like dotnet.exe. It is a console program, that helps, consider GenerateConsoleCtrlEvent().
– Hans Passant
Nov 23 '18 at 23:18
add a comment |
0
active
oldest
votes
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',
autoActivateHeartbeat: false,
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53453399%2fhow-to-use-terminateprocess-to-close-a-console-window%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53453399%2fhow-to-use-terminateprocess-to-close-a-console-window%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Right now you're flying blind. Check
TerminateProcess
's return value when you call it. If you get a return of zero, it failed and you may get more information fromGetLastError
.– user4581301
Nov 23 '18 at 22:12
1
Also worth noting
TerminateProcess
requests shutdown and returns. The other process will shut down later. It might be a while later.– user4581301
Nov 23 '18 at 22:13
Upvoted @RbMm, use
CreateProcess
– Tony J
Nov 23 '18 at 22:25
2
you create
cmd.exe
, it startconhost.exe
- you view theconhost.exe
window really. thencmd.exe
start you .NET application, which use the sameconhost.exe
. then you kill initialcmd.exe
. but this is invisible process - nothing seems to happen. theconhost.exe
exit only when no more process used it, but in your case it used by your .NET application - as result it not exit and command window still visible. you possible can create job (terminate all on close), useCreateProcess
in suspended state, assign it to job and resume.– RbMm
Nov 23 '18 at 22:44
You at best terminate cmd.exe, not the program(s) that were started by the .cmd file. Like dotnet.exe. It is a console program, that helps, consider GenerateConsoleCtrlEvent().
– Hans Passant
Nov 23 '18 at 23:18