The ::_tsystem()
function internally uses the CMD.EXE tool to run your command, and CMD.EXE is a console program, so you cannot prevent the console window from showing.
::_tsystem()函数在内部使用cmd.exe工具来运行您的命令,而cmd.exe是一个控制台程序,因此您无法阻止显示控制台窗口。
If you want to that you'll have to run the program using the proper Win32 API call: CreateProcess()
. It is a bit more convoluted, but not too much:
如果您想这样做,则必须使用正确的Win32API调用来运行该程序:CreateProcess()。这有点复杂,但也不算太复杂:
STARTUPINFO si;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
PROCESS_INFORMATION pi;
TCHAR cmd[] = _T("taskkill /F /T /IM MSC.EXE");
BOOL res = CreateProcess(NULL,
cmd,
NULL, NULL,
FALSE, CREATE_NO_WINDOW,
NULL, NULL,
&si, &pi);
if (!res)
error();
else
{
CloseHandle(hProcess);
CloseHandle(hThread);
}
Note the flag CREATE_NO_WINDOW
to avoid creating a console window even if the program is a console-type application.
请注意标志CREATE_NO_WINDOW以避免创建控制台窗口,即使程序是控制台类型的应用程序也是如此。
And beware of the cmd
parameter!. From the docs:
注意cmd参数!从文档中:
The Unicode version of this function, CreateProcessW, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a constant string, the function may cause an access violation.
So you must use a local array or characters (TCHAR[]), never a literal string.
因此,您必须使用本地数组或字符(TCHAR[]),而不是文字字符串。
Also note that when the function succeeds, the PROCESS_INFORMATION struct returns two open handles, one for the newly created process and another for its main thread. It is your responsibility to close these handles, or they will leak.
还要注意,当函数成功时,PROCESS_INFORMATION结构返回两个打开的句柄,一个用于新创建的进程,另一个用于其主线程。关好这些把手是你的责任,否则会漏水的。
Moreover, you can use the pi.hProcess
to wait for the process to finish:
此外,您可以使用pi.hProcess等待进程完成:
WaitForSingleObject(pi.hProcess, INFINITE);
have you tried something like:
你有没有尝试过这样的东西:
::_tsystem( _T("cmd /Q /C taskkill /F /T /IM MSC.exe") );
EDIT
编辑
Given that nothing seems to be working using system, ShellExecute is your best bet. I think the implementation would look something like this:
考虑到使用系统似乎什么都不起作用,ShellExecute是您最好的选择。我认为实现应该是这样的:
::ShellExecute(NULL, NULL, L"taskkill", L"/F /T /IM MSC.exe", NULL, SW_HIDE);
I have done the following to kill an external process by executing a hidden command prompt and line.
我执行了以下操作,通过执行隐藏的命令提示符和行来终止外部进程。
PROCESS_INFORMATION ProcessInfo;
STARTUPINFO StartupInfo;
LPSTR cmdArgs = "taskkill /F /T /IM MSC.exe";
StartupInfo.cb = sizeof(StartupInfo);
StartupInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
StartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
StartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
StartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
StartupInfo.wShowWindow = SW_HIDE;
CreateProcess(NULL,cmdArgs,NULL,NULL,false,NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW,NULL,NULL,&StartupInfo,&ProcessInfo);
Enjoy.
好好享受吧。
I second that you should use CreateProcess -- but you should definitely not use it directly. Why?
Because CreateProcess() is creating a resource
(the two handles, one for the process and one for the main thread)
which need to be closed when not needed anymore and after CreateProcess() was successful.
CreateProcess() belongs into the constructor and CloseHandle() (twice) into the destructor.
In case of CreateProcess() fails, you abort the constructor by throwing an exception,
whicb gets passed the return value of GetLastError() and potentially a string explaining that CreateProcess() failed. This exception type should convert the error code into the system error string.
我建议您应该使用CreateProcess--但绝对不应该直接使用它。为什么?因为CreateProcess()正在创建一个资源(两个句柄,一个用于进程,一个用于主线程),当不再需要时和CreateProcess()成功后,需要关闭该资源。CreateProcess()属于构造函数,而CloseHandle()(两次)属于析构函数。在CreateProcess()失败的情况下,通过抛出异常来中止构造函数,该异常向构造函数传递GetLastError()的返回值,并可能传递一个字符串来解释CreateProcess()失败。此异常类型应将错误代码转换为系统错误字符串。
Please leave this C programming philosophy behind you.
Use C++ as such and not as C!
请把这个C编程哲学抛在脑后。使用C++,而不是C!
Came to this in search of the same answer but ended up finding my own way within the docs(msdn) 'cause I didn't want to deal with CreateWindow and all that as I like things I can-mostly-remember easier for the next time I have to research it again.
我来到这里是为了寻找同样的答案,但最终在文档(MSDN)中找到了自己的方式,因为我不想处理CreateWindow和所有我喜欢的东西-主要是-记住更容易,以便下一次我必须再次研究它。
So I've come back here to share another way that works that's much simpler, imo, and achieves exactly what you're looking for; no annoying black box popup commands.
所以我回到这里来分享另一种更简单的工作方式,IMO,它实现了你想要的东西;没有恼人的黑框弹出命令。
System::Diagnostics::Process^ p = gcnew System::Diagnostics::Process();
p->StartInfo->UseShellExecute = false;
p->StartInfo->FileName = "cmd"; //yes, use cmd
p->StartInfo->Arguments = "/c taskkill /f /t /im MSC.exe"; //yes, use /c in the beginning. All the rest after /c is your normal commands you would run
p->StartInfo->CreateNoWindow = true;
p->Start();
更多回答
Thank you very much.. This works .. I have noticed thought, that if I need to wait for the process to finish I have to call CloseHandle(..)
after WaitForSingleObject(pi.hProcess, INFINITE);
非常感谢你..这很管用..我注意到,如果我需要等待进程完成,我必须调用CloseHandle(..)在WaitForSingleObject(pi.hProcess,无限)之后;
Nice work! But please see my new answer with a few details that you are missing. Moreover, you do not need that handle stuff, as you are not redirecting input nor output.
干得好!但请看我的新答案,其中有一些你遗漏的细节。此外,您不需要该句柄,因为您不需要重定向输入或输出。
我是一名优秀的程序员,十分优秀!