# HG changeset patch # User Andre Heinecke # Date 1406137679 -7200 # Node ID 8de162b91a222b4bb5c5bd5b099448e059b4ed63 # Parent 4aa33c408776ef259c1eba5547000b48d57af954 (Issue49) Create a Scheduled daily task to run trustbridge diff -r 4aa33c408776 -r 8de162b91a22 ui/CMakeLists.txt --- a/ui/CMakeLists.txt Mon Jul 21 18:53:13 2014 +0200 +++ b/ui/CMakeLists.txt Wed Jul 23 19:47:59 2014 +0200 @@ -40,6 +40,7 @@ ${CMAKE_CURRENT_SOURCE_DIR}/processhelp_linux.cpp ${CMAKE_CURRENT_SOURCE_DIR}/processwaitdialog.cpp ${CMAKE_CURRENT_SOURCE_DIR}/textoverlaybutton.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/taskscheduler.cpp ${CERTIFICATELIST_SOURCES} ${DOWNLOADER_SOURCES} ) @@ -94,8 +95,9 @@ set(WINDOWS_EXTRA_LIBS -L${_qtpath} -lwinspool -lshlwapi -lfreetype -lbz2 -lpng16 - -lQt5PlatformSupport -lQt5Gui -lcomdlg32 -loleaut32 -limm32 -lwinmm - -lglu32 -lopengl32 -lgdi32 -ljpeg -lpng -lQt5Core -lole32 -luuid -lws2_32 + -lQt5PlatformSupport -lQt5Gui -lcomdlg32 -loleaut32 -limm32 + -lharfbuzz -lglib-2.0 -lintl -liconv -lwinmm + -lglu32 -lopengl32 -lgdi32 -ljpeg -lpng -lQt5Core -lole32 -lmstask -luuid -lws2_32 -ladvapi32 -lshell32 -luser32 -lkernel32 -lz -lsicuin -lsicuuc -lsicudt -lpcre16) set(EXTRA_STATIC_LIBS Qt5::QWindowsIntegrationPlugin ${WINDOWS_EXTRA_LIBS} -lwinhttp -lcrypt32) diff -r 4aa33c408776 -r 8de162b91a22 ui/main.cpp --- a/ui/main.cpp Mon Jul 21 18:53:13 2014 +0200 +++ b/ui/main.cpp Wed Jul 23 19:47:59 2014 +0200 @@ -9,6 +9,9 @@ #include "processhelp.h" #include "logging.h" #include "selftest.h" +#ifdef WIN32 +#include "taskscheduler.h" +#endif #include #include @@ -97,6 +100,14 @@ return 1; } +#ifdef Q_OS_WIN + { + TaskScheduler taskSched; + qDebug() << " task sched done: " << taskSched.createDailyTask(QCoreApplication::applicationFilePath(), + QString::fromLatin1("--tray"), QTime::currentTime()); + } +#endif + MainWindow mainWin(trayMode); return app.exec(); diff -r 4aa33c408776 -r 8de162b91a22 ui/taskscheduler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/taskscheduler.cpp Wed Jul 23 19:47:59 2014 +0200 @@ -0,0 +1,188 @@ +#ifdef WIN32 +#include "taskscheduler.h" + +/* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik + * Software engineering by Intevation GmbH + * + * This file is Free Software under the GNU GPL (v>=2) + * and comes with ABSOLUTELY NO WARRANTY! + * See LICENSE.txt for details. + */ + +#include + +#include +#include +#include + +#define TASK_NAME L"TrustBridge Update" + +TaskScheduler::TaskScheduler() : + mInitialized (false), + mTaskScheduler (NULL) +{ + HRESULT hr; + + hr = CoInitialize(NULL); + if(FAILED(hr)) { + qDebug() << "TaskScheduler CoInitializeEx failed: " << hr; + return; + } + + hr = CoCreateInstance(CLSID_CTaskScheduler, + NULL, + CLSCTX_INPROC_SERVER, + IID_ITaskScheduler, + (void**)&mTaskScheduler); + if(FAILED(hr)) { + qDebug() << "TaskScheduler create instance failed: " << hr; + CoUninitialize(); + return; + } + + mInitialized = true; + qDebug() << "Initialization done"; + return; +} + +TaskScheduler::~TaskScheduler() { + qDebug() << "TaskSched dtor;"; + + if (!isInitialized()) { + return; + } + mTaskScheduler->Release(); + CoUninitialize(); +} + +bool createTrigger(ITask *task, const QTime &startTime) +{ + ITaskTrigger *pITaskTrigger = NULL; + WORD piNewTrigger = 0; + HRESULT hr; + TASK_TRIGGER pTrigger; + ZeroMemory(&pTrigger, sizeof (TASK_TRIGGER)); + QDate startdate = QDate::currentDate(); + + if (!startTime.isValid() || task == NULL) { + qDebug() << "Invalid args."; + return false; + } + + hr = task->CreateTrigger(&piNewTrigger, + &pITaskTrigger); + + if (FAILED(hr)) { + qDebug() << "Failed to create trigger."; + return false; + } + + pTrigger.wBeginDay = startdate.day(); + pTrigger.wBeginMonth = startdate.month(); + pTrigger.wBeginYear = startdate.year(); + pTrigger.wStartHour = startTime.hour(); + pTrigger.wStartMinute = startTime.minute(); + pTrigger.cbTriggerSize = sizeof (TASK_TRIGGER); + pTrigger.TriggerType = TASK_TIME_TRIGGER_DAILY; + pTrigger.Type.Daily.DaysInterval = 1; + + hr = pITaskTrigger->SetTrigger(&pTrigger); + + pITaskTrigger->Release(); + if (FAILED(hr)) { + qDebug() << "Failed to create trigger."; + return false; + } + + return true; +} + +bool TaskScheduler::createDailyTask(const QString &executable, + const QString &args, + const QTime &startTime) { + ITask *task = NULL; + IPersistFile *persistFile = NULL; + HRESULT hr; + + hr = mTaskScheduler->NewWorkItem(TASK_NAME, + CLSID_CTask, + IID_ITask, + (IUnknown**)&task); + + if (FAILED(hr)) { + qDebug() << "Failed to create new work item."; + return false; + } + + /* Set the task parameters */ + hr = task->SetApplicationName(reinterpret_cast (executable.utf16())); + if (FAILED(hr)) { + qDebug() << "Failed to set application name."; + task->Release(); + return false; + } + + hr = task->SetParameters(reinterpret_cast (args.utf16())); + if (FAILED(hr)) { + qDebug() << "Failed to set parameters."; + task->Release(); + return false; + } + + hr = task->SetComment(reinterpret_cast(QObject::tr("TrustBridge automatic update check.").utf16())); + if (FAILED(hr)) { + qDebug() << "Failed to set comment."; + task->Release(); + return false; + } + + QString username = QString::fromLocal8Bit(qgetenv("USERNAME").constData()); + if (username.isEmpty()) { + qDebug() << "Failed to obtain username from envrionment."; + task->Release(); + return false; + } + + hr = task->SetAccountInformation(reinterpret_cast(username.utf16()), NULL); + + if (FAILED(hr)) { + qDebug() << "Failed to set username."; + task->Release(); + return false; + } + + hr = task->SetFlags(TASK_FLAG_RUN_ONLY_IF_LOGGED_ON); + + if (FAILED(hr)) { + qDebug() << "Failed to set flags."; + task->Release(); + return false; + } + + /* Now create the trigger for this task */ + if (!createTrigger(task, startTime)) { + qDebug() << "Failed to create trigger."; + task->Release(); + return false; + } + + hr = task->QueryInterface(IID_IPersistFile, + (void **)&persistFile); + task->Release(); + + if (FAILED(hr)) { + qDebug() << "Failed to get persist file interface."; + task->Release(); + return false; + } + + hr = persistFile->Save(NULL, TRUE); + persistFile->Release(); + if (FAILED(hr)) { + qDebug() << "Failed to save task"; + return false; + } + + return true; +} +#endif /* WIN32 */ diff -r 4aa33c408776 -r 8de162b91a22 ui/taskscheduler.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/taskscheduler.h Wed Jul 23 19:47:59 2014 +0200 @@ -0,0 +1,51 @@ +/* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik + * Software engineering by Intevation GmbH + * + * This file is Free Software under the GNU GPL (v>=2) + * and comes with ABSOLUTELY NO WARRANTY! + * See LICENSE.txt for details. + */ +#ifndef TASKSCHEDULER_H +#define TASKSCHEDULER_H + +/** + * @file Interface to the Task Scheduler API + * @brief Provides a Qt / C++ API to work with the windows task scheduler + */ + +#include +#include +#ifndef INITGUID +#define INITGUID +#include +#undef INITGUID +#endif + +//struct ITaskScheduler; + +class TaskScheduler +{ +public: + /** @brief Initializes the COM objects */ + TaskScheduler(); + + /**@brief Uninitializes the COM objects */ + ~TaskScheduler(); + /** @brief create a task that is executed daily if the user is logged in. + * + * @param[in] executable Absolute path to the executable to run. + * @param[in] args the arguements to pass to the executable. + * @param[in] startTime the preferred time to start the task. + * + * @returns True on success, false on error */ + bool createDailyTask(const QString &executable, const QString &args, const QTime &startTime); + + /** @brief check if the Initialization was successful */ + bool isInitialized() {return mInitialized;} + +private: + bool mInitialized; + ITaskScheduler *mTaskScheduler; +}; + +#endif // TASKSCHEDULER_H