Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "WatchDog.h"
- #include <QMessageBox>
- #include <QCoreApplication>
- #include <QFile>
- #include <QMenu>
- #include <QCloseEvent>
- #include <QProcess>
- #include <QFileInfo>
- #include <QDateTime>
- #include <QRegExp>
- #include <string>
- #include "BorIni.h"
- #include <tlhelp32.h>
- const int INTERVAL_SEC = 15;
- const char * const COMMON_SECTION = "common";
- WatchDog::WatchDog( QWidget * parent, Qt::WFlags flags )
- : QDialog( parent, flags )
- {
- ui.setupUi( this );
- m_restoreAction = new QAction( QIcon( ":/images/restore" ), "Восстановить", this );
- connect( m_restoreAction, SIGNAL( triggered() ), this, SLOT( showNormal() ) );
- QAction * quitAction = new QAction( QIcon( ":/images/close" ), "Выход", this );
- connect( quitAction, SIGNAL( triggered() ), qApp, SLOT( quit() ) );
- QMenu * trayIconMenu = new QMenu( this );
- trayIconMenu->addAction( m_restoreAction );
- trayIconMenu->addSeparator();
- trayIconMenu->addAction( quitAction );
- trayIconMenu->setDefaultAction( m_restoreAction );
- m_trayIcon = new QSystemTrayIcon( this );
- m_trayIcon->setContextMenu( trayIconMenu );
- m_trayIcon->setToolTip( "Watch Dog. v. 2.0.0" );
- connect( m_trayIcon
- , SIGNAL( activated( QSystemTrayIcon::ActivationReason ) )
- , SLOT( iconActivated( QSystemTrayIcon::ActivationReason ) )
- );
- QIcon icon = QIcon( ":/images/dog" );
- m_trayIcon->setIcon( icon );
- setWindowIcon( icon );
- m_trayIcon->show();
- BorIni ini( "./WatchDog.ini", true );
- m_timerInterval = ini.getInt( COMMON_SECTION, "interval (sec)", INTERVAL_SEC ) * 1000;
- std::vector< std::string > sections = ini.sections();
- for ( int i = 0, sectionsCount = sections.size(); i < sectionsCount; i++ )
- {
- const std::string & section = sections[ i ];
- if ( section == COMMON_SECTION )
- {
- continue;
- }
- ExeParams exeParam;
- exeParam.exeName = section.c_str();
- exeParam.startCommand = ini.getString( section, "startCommand", section ).c_str();
- std::vector< std::string > keys = ini.keys( section );
- for ( int k = 0, keysCount = keys.size(); k < keysCount; k++ )
- {
- const std::string & key = keys[ k ];
- if ( key == "startCommand" )
- {
- continue;
- }
- std::string mask = ini.getString( section, key );
- if ( ! mask.empty() )
- {
- exeParam.captionMasks.push_back( mask.c_str() );
- }
- }
- m_exeNames.push_back( exeParam );
- }
- startTimer( m_timerInterval );
- }
- WatchDog::~WatchDog()
- {
- }
- void WatchDog::setVisible( bool visible )
- {
- m_restoreAction->setEnabled( ! visible );
- QDialog::setVisible( visible );
- }
- void WatchDog::closeEvent( QCloseEvent * event )
- {
- if ( m_trayIcon->isVisible() )
- {
- hide();
- event->ignore();
- }
- }
- void WatchDog::iconActivated( QSystemTrayIcon::ActivationReason reason )
- {
- switch ( reason )
- {
- case QSystemTrayIcon::DoubleClick:
- if ( m_restoreAction->isEnabled() )
- {
- m_restoreAction->trigger();
- }
- break;
- }
- }
- void WatchDog::timerEvent( QTimerEvent * event )
- {
- m_windows.clear();
- EnumWindows( nextWindow, (LPARAM) this );
- for ( int i = 0, exeNamesSize = m_exeNames.size(); i < exeNamesSize; i++ )
- {
- const ExeParams & exeParam = m_exeNames[ i ];
- QString exe = exeParam.exeName.toLower();
- QString logReason;
- DWORD processId = getProcessId( exe );
- bool processFound = ( processId != 0 );
- if ( processFound && ! exeParam.captionMasks.isEmpty() )
- {
- for ( int j = 0, windowsSize = m_windows.size(); j < windowsSize; j++ )
- {
- HWND hWnd = m_windows[ j ];
- DWORD wndProcessId = (DWORD)-1;
- GetWindowThreadProcessId( hWnd, & wndProcessId );
- if ( wndProcessId == processId )
- {
- if ( isCaptionMatches( hWnd, exeParam.captionMasks ) )
- {
- HANDLE hProcess = OpenProcess( PROCESS_TERMINATE, FALSE, processId );
- if ( hProcess != 0 )
- {
- TerminateProcess( hProcess, 0 );
- processFound = false;
- logReason = "обнаружено окно с заголовком \"" + getWindowCaption( hWnd ) + "\"";
- break;
- }
- }
- }
- }
- }
- else
- {
- logReason = "приложение отсутствует в списке процессов";
- }
- if ( processFound == false )
- {
- QProcess::startDetached( exeParam.startCommand, QStringList(), QFileInfo( exe ).absolutePath() );
- QFile logFile( "WatchDog.log" );
- if ( logFile.open( QIODevice::Append | QIODevice::Text ) )
- {
- QString msg = QDateTime::currentDateTime().toString( "dd.MM.yyyy hh:mm:ss.zzz" ) +
- " " + QFileInfo( exe ).fileName() + " " + logReason + " перезапуск\n";
- logFile.write( msg.toAscii() );
- }
- break;
- }
- }
- }
- BOOL CALLBACK WatchDog::nextWindow( HWND hwnd, LPARAM lParam )
- {
- WatchDog * self = (WatchDog*)lParam;
- self->m_windows.push_back( hwnd );
- return TRUE;
- }
- DWORD WatchDog::getProcessId( const QString & exe )
- {
- // Take a snapshot of all processes in the system.
- HANDLE hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
- if ( INVALID_HANDLE_VALUE == hProcessSnap )
- {
- QMessageBox::critical( 0, "Ошибка", "CreateToolhelp32Snapshot вернула INVALID_HANDLE_VALUE" );
- QCoreApplication::quit();
- return 0;
- }
- DWORD processId = 0;
- // Fill in the size of the structure before using it.
- PROCESSENTRY32 pe32 = {0};
- pe32.dwSize = sizeof( PROCESSENTRY32 );
- if ( Process32First( hProcessSnap, &pe32 ) )
- {
- do
- {
- QString processName = QString::fromWCharArray( pe32.szExeFile ).toLower();
- if ( exe.endsWith( processName ) )
- {
- processId = pe32.th32ProcessID;
- break;
- }
- }
- while ( Process32Next( hProcessSnap, &pe32 ) );
- }
- CloseHandle( hProcessSnap );
- return processId;
- }
- QString WatchDog::getWindowCaption( HWND hwnd )
- {
- QString caption;
- int captionLength = GetWindowTextLengthA( hwnd );
- if ( captionLength != 0 )
- {
- char * c_caption = new char[ captionLength + 1 ];
- GetWindowTextA( hwnd, c_caption, captionLength + 1 );
- caption = c_caption;
- delete []c_caption;
- }
- return caption;
- }
- bool WatchDog::isCaptionMatches( HWND hwnd, const QStringList & masks )
- {
- QString windowCaption = getWindowCaption( hwnd );
- for ( int i = 0, masksCount = masks.size(); i < masksCount; i++ )
- {
- QRegExp rx( masks[ i ] );
- rx.setPatternSyntax( QRegExp::Wildcard );
- if ( rx.indexIn( windowCaption ) != -1 )
- {
- return true;
- }
- }
- return false;
- }
Add Comment
Please, Sign In to add comment