Run a CMD command in Qt without displaying the CMD window

Run a CMD command in Qt without displaying the CMD window

It’s necessary to execute system commands sometime. system() is the most basic, it’s easy but cannot hide the black command line window, its options are not much enough. Here’re some better ways.


Method 1: system

​ It’s the most basic method not only used in Qt, you should include the library stdlib.h.

But, you have to see the ugly black cmd window.

Header
stdlib.h

Syntax

int system (const char* command);

Parameters

command:

​ C-string containing the system command to be executed. Or, alternatively, a null pointer, to check for a command processor.

Return Value

​ If command is a null pointer, the function returns a non-zero value in case a command processor is available and a zero value if it is not. If command is not a null pointer, the value returned depends on the system and library implementations, but it is generally expected to be the status code returned by the called command, if supported.

Example

/******example: ping******/
#include <stdio.h>
#include <stdlib.h>

int main()
{
	printf("checking processor\n");
	if (system(NULL)) puts ("Ok");
    	else exit (EXIT_FAILURE);
	printf("start ping\n");
	system("ping localhost >> res.txt");
	return 0;
}

​ You can see the ping’s result in res.txt after running these code.

Is here some method I can take to avoid displaying the cmd window? The answer is: YES.

Method 2: WinExec – without cmd window

WinExec() is another way to run a command, the advantage of using WinExec() is you don’t need to display the window, it means, you can hide the window. It needs winbase.h & windows.h.

BUT, this function is provided only for compatibility with 16-bit Windows. Applications should use the CreateProcess() function(as follows).

Header
windows.h
winbase.h

Syntax

UINT WinExec(
  LPCSTR lpCmdLine,
  UINT   uCmdShow
);

Parameters

lpCmdLine:

​ The command line (file name plus optional parameters) for the application to be executed.

uCmdShow:

​ The display options.

​ List of the acceptable values:

ValueMeaning
SW_HIDE 0Hides the window and activates another window.
SW_SHOWNORMAL SW_NORMAL 1Activates and displays a window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when displaying the window for the first time.
SW_SHOWMINIMIZED 2Activates the window and displays it as a minimized window.
SW_SHOWMAXIMIZED SW_MAXIMIZE 3Activates the window and displays it as a maximized window.
SW_SHOWNOACTIVATE 4Displays a window in its most recent size and position. This value is similar to SW_SHOWNORMAL, except that the window is not activated.
SW_SHOW 5Activates the window and displays it in its current size and position.
SW_MINIMIZE 6Minimizes the specified window and activates the next top-level window in the Z order.
SW_SHOWMINNOACTIVE 7Displays the window as a minimized window. This value is similar to SW_SHOWMINIMIZED, except the window is not activated.
SW_SHOWNA 8Displays the window in its current size and position. This value is similar to SW_SHOW, except that the window is not activated.
SW_RESTORE 9Activates and displays the window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when restoring a minimized window.
SW_SHOWDEFAULT 10Sets the show state based on the SW_ value specified in the STARTUPINFO structure passed to the CreateProcess() function by the program that started the application.
SW_FORCEMINIMIZE 11Minimizes a window, even if the thread that owns the window is not responding. This flag should only be used when minimizing windows from a different thread.

Return value

​ If the function succeeds, the return value is greater than 31.

​ If the function fails, the return value is one of the following error values.

Return code/valueDescription
0The system is out of memory or resources.
ERROR_BAD_FORMATThe .exe file is invalid.
ERROR_FILE_NOT_FOUNDThe specified file was not found.
ERROR_PATH_NOT_FOUNDThe specified path was not found.

Example

/******example: ping******/
#include <stdio.h>
#include <windows.h>
#include <winbase.h>

int main()
{
	printf("start ping\n");
	WinExec("cmd.exe /c ping localhost >> res.txt", SW_HIDE);	
	/*
	'/c' can't be ignored as you have arguments after 'cmd.exe'
	*/
	return 0;
}

​ With this function you cannot determine whether the command is completed, because it is executed asynchronously.

​ You must use CreateProcess() to solve the problem.

Method 3: CreateProcess – without cmd window

​ This function is used to run a new program. It creates a new process and its primary thread. The new process executes the specified executable file.

Header
windows.h

Syntax

BOOL CreateProcess( 
	LPCWSTR lpszImageName, 
	LPCWSTR lpszCmdLine, 
	LPSECURITY_ATTRIBUTES lpsaProcess, 
	LPSECURITY_ATTRIBUTES lpsaThread, 
	BOOL fInheritHandles, 
	DWORD fdwCreate, 
	LPVOID lpvEnvironment, 
	LPWSTR lpszCurDir, 
	LPSTARTUPINFOW lpsiStartInfo, 
	LPPROCESS_INFORMATION lppiProcInfo
); 

Parameters

lpszImageName: Pointer to a null-terminated string that specifies the module to execute.

​ The string can specify the full path and filename of the module to execute or it can specify a partial path and filename.

​ The lpszImageName parameter must be non-NULL and must include the module name.

lpszCmdLine: Pointer to a null-terminated string that specifies the command line to execute. The system adds a null character to the command line, trimming the string if necessary, to indicate which file was actually used.

​ The lpszCmdLine parameter can be NULL. In that case, the function uses the string pointed to by lpszImageName as the command line.

​ If both lpszImageName and lpszCmdLine are non-NULL, *lpszImageName specifies the module to execute, and *lpszCmdLine specifies the command line. C runtime processes can use the argc and argv arguments.

​ If the filename does not contain an extension, .EXE is assumed. If the filename ends in a period (.) with no extension, or the filename contains a path, .EXE is not appended.

lpsaProcess: Process safety attributes

lpsaThread: Thread safety attributes

fInheritHandles: Whether to inherit the attributes of the parent process

fdwCreate: Specifies additional flags that control the priority class and the creation of the process. The following creation flags can be specified in any combination, except as noted:

ValueDescription
CREATE_DEFAULT_ERROR_MODENot supported.
CREATE_NEW_CONSOLEThe new process has a new console, instead of inheriting the parent’s console. This flag cannot be used with the DETACHED_PROCESS flag.
CREATE_NEW_PROCESS_GROUPNot supported.
CREATE_SEPARATE_WOW_VDMNot supported.
CREATE_SHARED_WOW_VDMNot supported.
CREATE_SUSPENDEDThe primary thread of the new process is created in a suspended state, and does not run until the ResumeThread function is called.
CREATE_UNICODE_ENVIRONMENTNot supported.
DEBUG_PROCESSIf this flag is set, the calling process is treated as a debugger, and the new process is a process being debugged. Child processes of the new process are also debugged. The system notifies the debugger of all debug events that occur in the process being debugged.
 If you create a process with this flag set, only the calling thread (the thread that called CreateProcess) can call the WaitForDebugEvent function.
DEBUG_ONLY_THIS_PROCESSIf this flag is set, the calling process is treated as a debugger, and the new process is a process being debugged. No child processes of the new process are debugged. The system notifies the debugger of all debug events that occur in the process being debugged.
DETACHED_PROCESSNot supported.

lpvEnvironment: Pointer to current environment.

lpszCurDir: Pointer to current directory.

lpsiStartInfo: Pointer to STARTUPINFO structure

lppiProcInfo: Pointer to a PROCESS_INFORMATION structure that receives identification information about the new process.

Example

Here’s the Microsoft’s example:

#include <windows.h>
#include <stdio.h>
#include <tchar.h>

void _tmain( int argc, TCHAR *argv[] )
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    si.wShowWindow = SW_HIDE;	//hide window
    ZeroMemory( &pi, sizeof(pi) );

    // Start the child process. 
    if( !CreateProcess( NULL,   // No module name (use command line)
        "cmd.exe /c ping localhost >> res.txt",        // Command line
        NULL,           // Process handle not inheritable
        NULL,           // Thread handle not inheritable
        FALSE,          // Set handle inheritance to FALSE
        0,              // No creation flags
        NULL,           // Use parent's environment block
        NULL,           // Use parent's starting directory 
        &si,            // Pointer to STARTUPINFO structure
        &pi )           // Pointer to PROCESS_INFORMATION structure
    ) 
    {
        printf( "CreateProcess failed (%d).\n", GetLastError() );
        return;
    }

    // Wait until child process exits.
    WaitForSingleObject( pi.hProcess, INFINITE );

    // Close process and thread handles. 
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );
}

Method 4: QProcess – without cmd window

The QProcess class is used to start external programs and to communicate with them. It’s a modern method to run a command.

HeaderQProcess
qmakeQT += core

Examples

 QProcess p(0);
    p.start("cmd", QStringList()<<"/c"<<"ping localhost >> res.txt");
    p.waitForStarted();
    p.waitForFinished();

Another way:

QProcess p(0);
QString command = "cmd.exe";
QStringList args;
args.append("/c");
args.append("ping");
args.append("localhost");
args.append(">>");
args.append("res.txt");

p.execute(command, args);
p.waitForFinished();

//p.start(command, args);
//p.waitForStarted();
//p.waitForFinished();

Full example:

//file: "mainwindow.h"
#ifndef MAINWINDOW_H  
#define MAINWINDOW_H  

#include <QtGui>  

class MainWindow : public QMainWindow  
{  
    Q_OBJECT  

public:  
    MainWindow(QWidget *parent = 0);  
    
    ~MainWindow();  

private slots:  
    void openProcess(); 
    
    void readResult(int exitCode);  

private:  
    QProcess *p;  
};  

#endif // MAINWINDOW_H 
//file: "mainwindow.cpp"
#include "mainwindow.h"  
 
MainWindow::MainWindow(QWidget *parent)  
    : QMainWindow(parent)  
{  
    p = new QProcess(this);  
    QPushButton *bt = new QPushButton("execute", this);  
    connect(bt, SIGNAL(clicked()), this, SLOT(openProcess()));  
}  
 
MainWindow::~MainWindow()  
{  
 
}  
 
void MainWindow::openProcess()  
{  
    p->start("cmd.exe", QStringList() << "/c" << "ping localhost >> res.txt");  
    connect(p, SIGNAL(finished(int)), this, SLOT(readResult(int)));  
}  
 
void MainWindow::readResult(int exitCode)  
{  
    if(exitCode == 0) 
    {  
        QTextCodec* gbkCodec = QTextCodec::codecForName("GBK");  
        QString result = gbkCodec -> toUnicode(p -> readAll());   
    }  
}  

At last

At last, I recommand QProcess and CreateProcess.


© 2020-2021. All rights reserved.