0

I wanted to execute cmd command like "wmic logicaldisk get name > file.log". I have written the following function but it doesn't work and my program will crash.

bool Information::ExecuteConsoleCommand(QString arg_console_command)
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    ZeroMemory( &pi, sizeof(pi) );

    // Start the child process.
    if(!CreateProcess(NULL,
                      (WCHAR*)arg_console_command.toStdWString().c_str(),
                      NULL, NULL, FALSE,
                      NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW,
                      NULL, NULL, &si, &pi))
    {
        return false;
    }
    else
    {
        return true;
    }

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

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

How should I fix this function in the order it can execute cmd command? Also, I didn't want to use system() to run my commands because it show console window.

  • 1
    I think your bug is here `(WCHAR*)` if you need to cast a string type you are almost always making a mistake because the cast just silences the compilers error. It does not convert the type of string from a narrow to wide or vice versa. – drescherjm Jul 27 '20 at 00:39
  • You probably wanted [https://doc.qt.io/qt-5/qstring.html#toStdWString](https://doc.qt.io/qt-5/qstring.html#toStdWString) – drescherjm Jul 27 '20 at 00:44
  • you can't redirect output like that. See [How do I redirect output to a file with CreateProcess?](https://stackoverflow.com/q/7018228/995714) – phuclv Jul 27 '20 at 03:52
  • In `Qt` when I need to create a process on windows I still use `QProcess`. [https://doc.qt.io/qt-5/qprocess.html](https://doc.qt.io/qt-5/qprocess.html) – drescherjm Jul 27 '20 at 12:27

1 Answers1

1

I see tag Qt and parameter's type QString in your question. So, you can use QProcess and QFile, here is example:

#include <QProcess>
#include <QDebug>
#include <QFile>


int main(int /*argc*/, char* /*argv*/[])
{
    QProcess process;
    process.start("wmic logicaldisk get name");
    process.waitForFinished();

    auto output = process.readAll();

    QFile outputFile("file.log");
    outputFile.open(QIODevice::WriteOnly);
    outputFile.write(output);
    outputFile.close();

    return 0;
}

If you want to use CreateProcess, you can do it like this (based on your source):

#include <QString>
#include <Windows.h>


bool ExecuteConsoleCommand(QString arg_console_command)
{
    arg_console_command.prepend("/C ");

    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);

    // Start the child process.
    if(!CreateProcessW(L"C:\\Windows\\System32\\cmd.exe",
                      (WCHAR*)arg_console_command.toStdWString().c_str(),
                      NULL, NULL, FALSE,
                      NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW,
                      NULL, NULL, &si, &pi))
    {
        return false;
    }

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

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


int main(int /*argc*/, char* /*argv*/[])
{
    ExecuteConsoleCommand("wmic logicaldisk get name > file.log");
    return 0;
}
Ihor Drachuk
  • 1,265
  • 7
  • 17