forked from onnet/kazoo_popup
-
Notifications
You must be signed in to change notification settings - Fork 11
/
updatemanager.cpp
160 lines (134 loc) · 4.04 KB
/
updatemanager.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include "updatemanager.h"
#include "defaults.h"
#include <QTimer>
#include <QMutex>
#include <QApplication>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#ifdef Q_OS_WIN
# include <windows.h>
# include <shellapi.h>
#elif defined Q_OS_MAC
# include <QProcess>
# include <QDir>
#endif
UpdateManager *UpdateManager::m_instance = nullptr;
static int kUpdateMinInterval = 1; // 1 hour min interval
static int kUpdateMaxInterval = 5; // 5 hours max interval
static const char * const kCheckUpdateUrl = "http://updates.2600hz.com/checkupdate.php";
#ifdef Q_OS_WIN
static QString kUpdaterFileName = "autoupdater.exe";
static int kSuccessShellExecute = 32; // http://msdn.microsoft.com/en-us/library/windows/desktop/bb762153(v=vs.85).aspx
#elif defined Q_OS_MAC
static QString kUpdaterFileName = "autoupdater";
#endif
UpdateManager::UpdateManager(QObject *parent) :
QObject(parent)
{
m_timer = new QTimer();
qsrand(QDateTime::currentMSecsSinceEpoch());
connect(m_timer, &QTimer::timeout,
this, &UpdateManager::processTimeout);
}
UpdateManager *UpdateManager::instance()
{
if (m_instance == nullptr)
{
static QMutex mutex;
mutex.lock();
if (m_instance == nullptr)
m_instance = new UpdateManager;
mutex.unlock();
}
return m_instance;
}
void UpdateManager::start()
{
processTimeout();
}
void UpdateManager::stop()
{
m_timer->stop();
}
void UpdateManager::processTimeout()
{
checkUpdate();
int randValue = (qrand() % (kUpdateMaxInterval - kUpdateMinInterval + 1)) + kUpdateMinInterval;
m_timer->start(randValue * 60 * 60 * 1000);
}
void UpdateManager::checkUpdate(bool quiet)
{
QNetworkAccessManager *nam = new QNetworkAccessManager(this);
connect(nam, &QNetworkAccessManager::finished,
this, &UpdateManager::onReplyFinished);
QUrl url(kCheckUpdateUrl);
QString query("app=kazoo&platform=%1&ver=%2");
url.setQuery(query.arg(detectPlatform()).arg(APP_VERSION));
QNetworkReply *reply = nam->get(QNetworkRequest(url));
reply->setProperty("quiet", quiet);
}
void UpdateManager::onReplyFinished(QNetworkReply *reply)
{
QString data = reply->readAll();
bool quiet = reply->property("quiet").toBool();
if (!data.isEmpty() && data.startsWith("http"))
{
qDebug("New version is available");
m_updateUrl = data;
stop();
if (quiet)
doUpdate();
else
emit updateAvailable();
}
else
{
if (quiet)
emit noUpdate();
}
reply->manager()->deleteLater();
reply->deleteLater();
}
bool UpdateManager::doUpdate() const
{
QString updaterPath("%1/%2");
updaterPath = updaterPath.arg(qApp->applicationDirPath(), kUpdaterFileName);
bool ok;
#ifdef Q_OS_WIN
QString parameters("\"update\" \"%1\"");
parameters = parameters.arg(m_updateUrl);
int result = (int)ShellExecute(0,
L"open",
(const WCHAR*)updaterPath.utf16(),
(const WCHAR*)parameters.utf16(),
0,
SW_SHOWNORMAL);
if (result == SE_ERR_ACCESSDENIED)
{
// Requesting elevation
result = (int)ShellExecute(0,
L"runas",
(const WCHAR*)updaterPath.utf16(),
(const WCHAR*)parameters.utf16(),
0,
SW_SHOWNORMAL);
}
ok = (result > kSuccessShellExecute);
#elif defined Q_OS_MAC
QStringList arguments("update");
arguments.append(m_updateUrl);
ok = QProcess::startDetached(updaterPath, arguments);
#endif
if (!ok)
qWarning() << "Unable to start updater from path: " << updaterPath;
else
QTimer::singleShot(0, qApp, SLOT(quit()));
return ok;
}
void UpdateManager::quietUpdate()
{
if (m_updateUrl.isEmpty())
checkUpdate(true);
else
doUpdate();
}