简体   繁体   English

在 QT 中执行 system() 命令时如何避免控制台闪烁/打开?

[英]How to avoid console flickering/opening when executing a system() command in QT?

I'm working on an implementation to force the exit of a process by PID in QT.我正在研究一种实现,以通过 QT 中的 PID 强制退出进程。 The only way I found to solve this problem is using the following lines of code:我发现解决此问题的唯一方法是使用以下代码行:

QString processToKill = "taskkill /F /PID " + QString(getAppPid());
system(processToKill.toStdString().c_str());    

These lines do their job and works well, the only detail I have found is that when executing this command a console opens and closes quickly (a flicker).这些行完成了它们的工作并且运行良好,我发现的唯一细节是,在执行此命令时,控制台会快速打开和关闭(闪烁)。 Is there any way to prevent this behavior?有什么办法可以防止这种行为?

If this is a windows program create a program that uses a WinMain entry point rather than main, and set the linker subsystem to windows rather than console.如果这是一个 windows 程序,请创建一个使用 WinMain 入口点而不是 main 的程序,并将 linker 子系统设置为 windows 而不是控制台。

Just because it uses WinMain does not mean that you must create a window, it merely means you don't automatically get a console.仅仅因为它使用 WinMain 并不意味着您必须创建一个 window,这仅意味着您不会自动获得控制台。

If you are using system() you cannot avoid the occasional flash of the console window.如果您使用的是system() ,则无法避免控制台 window 偶尔出现的 flash。 Were you to use any other program you might even see its window flash.如果您使用任何其他程序,您甚至可能会看到它的 window flash。

I won't go into any detail about the security flaws inherent to using system() .我不会 go 详细介绍使用system()固有的安全漏洞。

The correct way to do this with the Windows API.使用 Windows API 执行此操作的正确方法。

Even so, you are taking a sledgehammer approach.即便如此,你还是采取了大锤的方法。 You should first signal the process to terminate gracefully .您应该首先发出信号让进程正常终止 If it hasn't done so after a second or two, only then should you crash it.如果它在一两秒钟后还没有这样做,那么你才应该让它崩溃。

The SO question “ How to gracefully terminate a process ” details several options to properly ask a process to terminate. SO 问题“ 如何优雅地终止进程”详细说明了正确要求进程终止的几个选项。

If that fails, then you can simply kill a process using the TerminateProcess() Windows API function (which is what taskkill /f does).如果失败了,那么您可以简单地使用TerminateProcess() Windows API function杀死一个进程(这就是taskkill /f所做的)。 Here is a good example of how to do that: https://github.com/malcomvetter/taskkill这是一个很好的例子: https://github.com/malcomvetter/taskkill

The relevant code has the following function: 相关代码有以下function:

BOOL TerminateProcess(int pid)
{
    WORD dwDesiredAccess = PROCESS_TERMINATE;
    BOOL bInheritHandle = FALSE;
    HANDLE hProcess = OpenProcess(dwDesiredAccess, bInheritHandle, pid);
    if (hProcess == NULL)
        return FALSE;
    BOOL result = TerminateProcess(hProcess, 1);
    CloseHandle(hProcess);
    return(TRUE);
}

Microsoft has a page all about Terminating a Process that you may wish to review as well. Microsoft 有一个关于终止进程的页面,您可能也希望查看该页面。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM