Forum


Notice to all users

We are migrating towards a new forum system located at community.teamspeak.com, as such this forum will become read-only on January 29, 2020

Results 1 to 6 of 6
  1. #1
    Join Date
    December 2014
    Location
    Germany
    Posts
    5

    Monitor TeamSpeak 3 Client on Windows 7

    Hello,

    I wrote a plugin which have to run 24/7. But sometimes the client crashes and until I found/fixed the error I want to write a little application which starts the client, log its stdout and stderr and restart the client on crash.

    I program with C++ and Qt 5.3 and wanted to use QProcess. But when it should start the TeamSpeak 3 Client it just outputs the error "Process failed to start: Insufficient permissions to invoke the program."

    This problem is TeamSpeak dependent, not c++ or Qt. When I pass "calc.exe" or "7zFM.exe" as argument my program runs without any problem. To use my program with TeamSpeak 3 I pass "C:\Users\Psy-Kai\AppData\Local\Team Speak 3 Client\ts3client_win64.exe" (where my TeamSpeak is located).

    Here my code:
    (main.c)
    Code:
    #include <QCoreApplication>
    #include <QTimer>
    #include "maincontroller.h"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        MainController c;
        QTimer::singleShot(0, &c, SLOT(run()));
    
        return a.exec();
    }
    (maincontroller.h)
    Code:
    #ifndef MAINCONTROLLER_H
    #define MAINCONTROLLER_H
    
    #include <QCoreApplication>
    #include <QProcess>
    
    class MainController : public QObject
    {
    Q_OBJECT
        enum QProcessSignal
        {
            ERROR = 0,
            FINISHED,
            READYREADSTANDARTERROR,
            READYREADSTANDARTOUTPUT,
            STARTED,
            STATECHANGED
        };
    
    
    public:
        explicit MainController();
    public slots:
        void run();
    private:
        void quitApplication();
        QProcess process_;
    private slots:
        void processError(QProcess::ProcessError error);
        void processFinished(int exit_code, QProcess::ExitStatus exit_status);
        void processReadyReadStandartError();
        void processReadyReadStandartOutput();
        void processStarted();
        void processStateChanged(QProcess::ProcessState new_state);
    };
    
    #endif // MAINCONTROLLER_H
    (maincontroller.cpp)
    Code:
    #include "maincontroller.h"
    
    #include <stdint.h>
    #include <QDir>
    #include <QDebug>
    #include <QThread>
    #include <QFileInfo>
    
    MainController::MainController() :
        QObject()
    {
        QObject::connect(&process_, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError)));
        QObject::connect(&process_, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(processFinished(int, QProcess::ExitStatus)));
        QObject::connect(&process_, &QProcess::readyReadStandardError, this, &MainController::processReadyReadStandartError);
        QObject::connect(&process_, &QProcess::readyReadStandardOutput, this, &MainController::processReadyReadStandartOutput);
        QObject::connect(&process_, &QProcess::started, this, &MainController::processStarted);
        QObject::connect(&process_, &QProcess::stateChanged, this, &MainController::processStateChanged);
    }
    
    void MainController::run()
    {
        QStringList arguments(QCoreApplication::arguments());
    
        if (arguments.count() > 0)
        {
            const QString app_name(QFileInfo(QCoreApplication::applicationFilePath()).fileName());
            if (QFileInfo(arguments.at(0)).fileName().compare(app_name) == 0)
            {
                arguments.removeFirst();
            }
    
            if (arguments.count() < 1)
            {
                quitApplication();
            }
            else
            {
                QFile programm(arguments[0]);
                if (programm.exists())
                {
                    process_.setProgram(arguments[0]);
    
                    arguments.removeFirst();
                    process_.setArguments(arguments);
    
                    process_.start();
                }
                else
                {
                    qWarning() << "Programm" << programm.fileName() << "not found.\nGonna end.";
                    QCoreApplication::quit();
                }
            }
        }
        else
        {
            quitApplication();
        }
    }
    
    void MainController::quitApplication()
    {
    qWarning() << "No arguments passed. Gonna end.";
    #ifdef Q_OS_WIN
        qWarning() << "Usage: .\\Programm_Watcher.exe /\"C:\\Program Files (x86)\\Internet Explorer\\iexplore.exe\"";
    #else
        qWarning() << "Usage: ./Programm_Watcher \"/bin/bash\""
    #endif
    
        QCoreApplication::quit();
    }
    
    void MainController::processError(QProcess::ProcessError error)
    {
        qDebug() << "Process" << process_.program() << "| Processsignal" << ERROR << "|" << "Error occurred:" << error << "-" << process_.errorString();
    }
    
    void MainController::processFinished(int exit_code, QProcess::ExitStatus exit_status)
    {
        qDebug() << "Process" << process_.program() << "| Processsignal" << FINISHED << "|" << "Finished. Exitcode:" << exit_code << "- Exitstatus:" << exit_status;
        qDebug() << "Gonna restart process" << process_.program() << "in";
        for (int32_t i(5); i>0; i--)
        {
            qDebug() << ".." << i;
            this->thread()->sleep(1);
        }
    
        process_.start();
    }
    
    void MainController::processReadyReadStandartError()
    {
        qDebug() << "Process" << process_.program() << "| Processsignal" << READYREADSTANDARTERROR << "|" << "Data from stderr:" << process_.readAllStandardError();
    }
    
    void MainController::processReadyReadStandartOutput()
    {
        qDebug() << "Process" << process_.program() << "| Processsignal" << READYREADSTANDARTOUTPUT << "|" << "Data from stdout:" << process_.readAllStandardOutput();
    }
    
    void MainController::processStarted()
    {
        qDebug() << "Process" << process_.program() << "| Processsignal" << STARTED << "|" << "Started.";
    }
    
    void MainController::processStateChanged(QProcess::ProcessState new_state)
    {
        qDebug() << "Process" << process_.program() << "| Processsignal" << STATECHANGED << "|" << "State changed:" << new_state;
    }

    Edit 1:
    If you can help me but want to ensure I am not writing a spam-bot (because oft the 24/7 client uptime) PN me and I will show you what my Plugin does
    Last edited by Psy-Kai; December 3rd, 2014 at 11:00 PM.

  2. #2
    Join Date
    October 2012
    Location
    Germany
    Posts
    553
    Could be an escaping issue for spaces and backslash for QProcess.
    Code:
    QProcess * process=new QProcess(this);
    QString temp="\"C:\\Program Files\\Internet Explorer\\iexplore.exe\"";
    process->startDetached(temp);
    Granted, that'd be an inconsistency to QFile, but stranger things have happened.

  3. #3
    Join Date
    December 2014
    Location
    Germany
    Posts
    5
    It is no escsping issue. I passed the full 7zip path (C:\Program Files\7-Zip\7zFM.exe) to test that

  4. #4
    Join Date
    September 2012
    Posts
    6,079
    Quote Originally Posted by Psy-Kai View Post
    Code:
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        MainController c;
        QTimer::singleShot(0, &c, SLOT(run()));
    
        return a.exec();
    }
    No need for the timer, could just do c.run() instead.


    Quote Originally Posted by Psy-Kai View Post
    (maincontroller.cpp)
    Code:
    void MainController::processFinished(int exit_code, QProcess::ExitStatus exit_status)
    {
        qDebug() << "Process" << process_.program() << "| Processsignal" << FINISHED << "|" << "Finished. Exitcode:" << exit_code << "- Exitstatus:" << exit_status;
        qDebug() << "Gonna restart process" << process_.program() << "in";
        for (int32_t i(5); i>0; i--)
        {
            qDebug() << ".." << i;
            this->thread()->sleep(1);
        }
    
        process_.start();
    }
    why the loop? It's equivalent to thread()->sleep(5) anyway.
    When sending PMs please make sure to include a reference link to the thread in question in the body of your message.

  5. #5
    Join Date
    December 2014
    Location
    Germany
    Posts
    5
    1. I want to run all my code in the eventloop. Thats why i use the 0 seconds timer.
    2. If you look at the for loop you may see, that i want to output the seconds till the restart ("..5 ..4 ..3 ..2 ..1" ). How should that work with a 5 seconfs sleep? O.o

  6. #6
    Join Date
    December 2014
    Location
    Germany
    Posts
    5
    Nobody could help me so I say how I do it now:

    on Linux you can start TeamSpeak3 in terminal or from another program. So I now have a Linux server (without gui) and vnc4server to start TeamSpeak. With this setup I can monitor what Teamspeak and my plugin does and restart Teamspeak if it crashs.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. [Evaluation] Monitor with 144Hz is laggy while TS is opened
    By Spacecraft in forum Windows
    Replies: 17
    Last Post: May 22nd, 2018, 03:21 AM
  2. Client Won't Remember Secondary Monitor Position
    By MadManMoon in forum Windows
    Replies: 1
    Last Post: December 22nd, 2012, 11:05 AM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •