RabbitCommon v2.2.6
Loading...
Searching...
No Matches
RabbitCommonRegister.cpp
1// Copyright Copyright (c) Kang Lin studio, All Rights Reserved
2// Author Kang Lin <kl222@126.com>
3
4#include "RabbitCommonRegister.h"
5#include "RabbitCommonDir.h"
6#include "Log/Log.h"
7#include "RabbitCommonTools.h"
8
9#include <QSettings>
10#include <QCoreApplication>
11#include <QDir>
12#include <QStandardPaths>
13
14namespace RabbitCommon {
15
16static Q_LOGGING_CATEGORY(log, "RabbitCommon.Register")
17
18const QString gKeyCurrentUserRun = "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run";
19const QString gKeyCurrentUserRunOnce = "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce";
20const QString gKeyCurrentUserRunServices = "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\RunServices";
21const QString gKeyCurrentUserRunServicesOnce = "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\RunServicesOnce";
22
23const QString gKeyRun = "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Run";
24const QString gKeyRunOnce = "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce";
25const QString gKeyRunServices = "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\RunServices";
26const QString gKeyRunServicesOnce = "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\RunServicesOnce";
27
28CRegister::CRegister()
29{
30}
31
32CRegister::~CRegister() {}
33
34int CRegister::InstallStartRunCurrentUser(QString szName, QString szPath)
35{
36#if defined (Q_OS_WIN)
37 return InstallStartRun(gKeyCurrentUserRun, szName, szPath);
38#elif defined(Q_OS_ANDROID)
39 //TODO: See https://www.cnblogs.com/jetereting/p/4572302.html
40
41 return 0;
42#elif defined(Q_OS_UNIX)
43 //See: debian/postinst and Install/install.sh
44 //Ubuntu use gnome-session-properties
45 // - Current user: ~/.config/autostart
46 // - All user: /etc/xdg/autostart/
47 //https://blog.csdn.net/DinnerHowe/article/details/79025282
48 QString szLink = GetDesktopFileLink(szName, false);
49 if(QFile::exists(szLink))
50 if(CTools::RemoveStartRun(szName, false))
51 {
52 qCCritical(log) << "RemoveStartRun" << szName << "fail";
53 return -1;
54 }
55
56 QString appPath = GetDesktopFileName(szPath, szName);
57 QFile f(appPath);
58 if(!f.exists())
59 {
60 qCCritical(log) << "The desktop file is not exist." << appPath;
61 return -1;
62 }
63 bool ret = f.link(szLink);
64 if(ret) return 0;
65
66 qCritical(log) << "f.link fail[" << f.error() << "]:" << f.errorString();
67 if(QFileDevice::RenameError == f.error()) return 0;
68
69 QString szCmd = "ln -s " + appPath + " " + szLink;
70 if(CTools::executeByRoot(szCmd)) return 0;
71 qCritical(log) << "execute" << szCmd << "fail";
72 return -1;
73#endif
74}
75
76int CRegister::RemoveStartRunCurrentUser(QString szName)
77{
78#if defined (Q_OS_WIN)
79 return RemoveStartRun(gKeyCurrentUserRun, szName);
80#elif defined(Q_OS_ANDROID)
81
82 return 0;
83#elif defined(Q_OS_UNIX)
84 QString szLink = GetDesktopFileLink(szName, false);
85 if(!QFile::exists(szLink)) return 0;
86
87 QDir d;
88 if(d.remove(szLink)) return 0;
89
90 QString szCmd = "rm " + szLink;
91 if(CTools::executeByRoot(szCmd)) return 0;
92 qCritical(log) << "execute" << szCmd << "fail";
93 return -1;
94#endif
95}
96
97bool CRegister::IsStartRunCurrentUser(QString szName)
98{
99#if defined (Q_OS_WIN)
100 return IsStartRun(gKeyCurrentUserRun, szName);
101#elif defined(Q_OS_ANDROID)
102
103 return false;
104#elif defined(Q_OS_UNIX)
105 QString szLink = GetDesktopFileLink(szName, false);
106 if(QFile::exists(szLink))
107 return true;
108 return false;
109#endif
110}
111
112int CRegister::InstallStartRunOnceCurrentUser(QString szName, QString szPath)
113{
114 return InstallStartRun(gKeyCurrentUserRunOnce, szName, szPath);
115}
116
117int CRegister::RemoveStartRunOnceCurrentUser(QString szName)
118{
119 return RemoveStartRun(gKeyCurrentUserRunOnce, szName);
120}
121
122bool CRegister::IsStartRunOnceCurrentUser(QString szName)
123{
124 return IsStartRun(gKeyCurrentUserRunOnce, szName);
125}
126
127int CRegister::InstallStartRunServicesCurrentUser(QString szName, QString szPath)
128{
129 return InstallStartRun(gKeyCurrentUserRunServices, szName, szPath);
130}
131
132int CRegister::RemoveStartRunServicesCurrentUser(QString szName)
133{
134 return RemoveStartRun(gKeyCurrentUserRunServices, szName);
135}
136
137bool CRegister::IsStartRunServicesCurrentUser(QString szName)
138{
139 return IsStartRun(gKeyCurrentUserRunServices, szName);
140}
141
142int CRegister::InstallStartRunServicesOnceCurrentUser(QString szName, QString szPath)
143{
144 return InstallStartRun(gKeyCurrentUserRunServicesOnce, szName, szPath);
145}
146
147int CRegister::RemoveStartRunServicesOnceCurrentUser(QString szName)
148{
149 return RemoveStartRun(gKeyCurrentUserRunServicesOnce, szName);
150}
151
152bool CRegister::IsStartRunServicesOnceCurrentUser(QString szName)
153{
154 return IsStartRun(gKeyCurrentUserRunServicesOnce, szName);
155}
156
157int CRegister::InstallStartRun(QString szName, QString szPath)
158{
159#if defined (Q_OS_WIN)
160 return InstallStartRun(gKeyRun, szName, szPath);
161#elif defined(Q_OS_ANDROID)
162 //TODO: See https://www.cnblogs.com/jetereting/p/4572302.html
163
164 return 0;
165#elif defined(Q_OS_UNIX)
166 //See: debian/postinst and Install/install.sh
167 //Ubuntu use gnome-session-properties
168 // - Current user: ~/.config/autostart
169 // - All user: /etc/xdg/autostart/
170 //https://blog.csdn.net/DinnerHowe/article/details/79025282
171 QString szLink = GetDesktopFileLink(szName, true);
172 if(QFile::exists(szLink))
173 if(CTools::RemoveStartRun(szName, true))
174 {
175 qCCritical(log) << "RemoveStartRun" << szName << "fail";
176 return -1;
177 }
178
179 QString appPath = GetDesktopFileName(szPath, szName);
180 QFile f(appPath);
181 bool ret = f.link(szLink);
182 if(!ret)
183 {
184 QString szCmd = "ln -s " + appPath + " " + szLink;
185 if(!CTools::executeByRoot(szCmd))
186 qCritical(log) << "CTools::InstallStartRun: file link"
187 << f.fileName() << " to " << szLink << f.error();
188 return -1;
189 }
190 return 0;
191#endif
192}
193
194int CRegister::RemoveStartRun(const QString &szName)
195{
196#if defined (Q_OS_WIN)
197 return RemoveStartRun(gKeyRun, szName);
198#elif defined(Q_OS_ANDROID)
199
200 return 0;
201#elif defined(Q_OS_UNIX)
202 QString szLink = CRegister::GetDesktopFileLink(szName, true);
203 if(!QFile::exists(szLink)) return 0;
204
205 QDir d;
206 if(d.remove(szLink)) return 0;
207
208 QString szCmd = "rm " + szLink;
209 if(CTools::executeByRoot(szCmd)) return 0;
210 qCritical(log) << "execute" << szCmd << "fail";
211 return -1;
212#endif
213}
214
215bool CRegister::IsStartRun(const QString &szName)
216{
217#if defined (Q_OS_WIN)
218 return IsStartRun(gKeyRun, szName);
219#elif defined(Q_OS_ANDROID)
220
221 return false;
222#elif defined(Q_OS_UNIX)
223 QString szLink = GetDesktopFileLink(szName, true);
224 if(QFile::exists(szLink))
225 return true;
226 return false;
227#endif
228}
229
230int CRegister::InstallStartRunOnce(QString szName, QString szPath)
231{
232 return InstallStartRun(gKeyRunOnce, szName, szPath);
233}
234
235int CRegister::RemoveStartRunOnce(QString szName)
236{
237 return RemoveStartRun(gKeyRunOnce, szName);
238}
239
240bool CRegister::IsStartRunOnce(QString szName)
241{
242 return IsStartRun(gKeyRunOnce, szName);
243}
244
245int CRegister::InstallStartRunServices(QString szName, QString szPath)
246{
247 return InstallStartRun(gKeyRunServices, szName, szPath);
248}
249
250int CRegister::RemoveStartRunServices(QString szName)
251{
252 return RemoveStartRun(gKeyRunServices, szName);
253}
254
255bool CRegister::IsStartRunServices(QString szName)
256{
257 return IsStartRun(gKeyRunServices, szName);
258}
259
260int CRegister::InstallStartRunServicesOnce(QString szName, QString szPath)
261{
262 return InstallStartRun(gKeyRunServicesOnce, szName, szPath);
263}
264
265int CRegister::RemoveStartRunServicesOnce(QString szName)
266{
267 return RemoveStartRun(gKeyRunServicesOnce, szName);
268}
269
270bool CRegister::IsStartRunServicesOnce(QString szName)
271{
272 return IsStartRun(gKeyRunServicesOnce, szName);
273}
274
275int CRegister::InstallStartRun(const QString &szKey, const QString &szName, const QString &szPath)
276{
277 Q_UNUSED(szKey);
278 Q_UNUSED(szName);
279 Q_UNUSED(szPath);
280
281 QString appName = QCoreApplication::applicationName();
282 QString appPath = QCoreApplication::applicationFilePath();
283 if(!szName.isEmpty())
284 appName = szName;
285 if(!szPath.isEmpty())
286 appPath = szPath;
287 appPath = appPath.replace("/", "\\");
288 return SetRegister(szKey, appName, appPath);
289}
290
291int CRegister::RemoveStartRun(const QString &szKey, const QString &szName)
292{
293 Q_UNUSED(szKey);
294 Q_UNUSED(szName);
295 QString appName = QCoreApplication::applicationName();
296 if(!szName.isEmpty())
297 appName = szName;
298 return RemoveRegister(szKey, appName);
299}
300
301bool CRegister::IsStartRun(const QString &szKey, const QString &szName)
302{
303 Q_UNUSED(szKey);
304 Q_UNUSED(szName);
305 QString appName = QCoreApplication::applicationName();
306
307 if(!szName.isEmpty())
308 appName = szName;
309 return IsRegister(szKey, appName);
310}
311
312int CRegister::SetRegister(const QString &reg, const QString &name, const QString &path)
313{
314 QSettings r(reg, QSettings::NativeFormat);
315 QString val = r.value(name).toString();
316 if(val != path)
317 r.setValue(name, path);
318 return 0;
319}
320
321int CRegister::RemoveRegister(const QString &reg, const QString &name)
322{
323 QSettings r(reg, QSettings::NativeFormat);
324 QString val = r.value(name).toString();
325 if(!val.isEmpty())
326 r.remove(name);
327 return 0;
328}
329
330bool CRegister::IsRegister(const QString &reg, const QString &name)
331{
332 QSettings r(reg, QSettings::NativeFormat);
333 QString val = r.value(name).toString();
334 return !val.isEmpty();
335}
336
337/*
338 * ubuntu icon of desktop position:
339 *
340 * - All user: /usr/share/applications or /usr/local/share/applications
341 * - Current user: ~/.local/share/applications
342 *
343 * See: debian/postinst
344 * See: https://blog.csdn.net/jiang_huixin/article/details/107092622
345 */
346QString CRegister::GetDesktopFileName(const QString &szPath,
347 const QString &szName)
348{
349 QString appName = "org.Rabbit." + qApp->applicationName() + ".desktop";
350 if(!szName.isEmpty())
351 appName = szName;
352
353 QString appPath = CDir::Instance()->GetDirApplicationInstallRoot()
354 + "/share/applications";
355 if(!szPath.isEmpty())
356 appPath = szPath;
357
358 return appPath + QDir::separator() + appName;
359}
360
361/*
362 //See: debian/postinst and Install/install.sh
363 //Ubuntu use gnome-session-properties
364 // - Current user: ~/.config/autostart
365 // - All user: /etc/xdg/autostart/
366 //https://blog.csdn.net/DinnerHowe/article/details/79025282
367 */
368QString CRegister::GetDesktopFileLink(const QString &szName, bool bAllUser)
369{
370 QString appName
371 = "org.Rabbit." + QCoreApplication::applicationName() +".desktop";
372 if(!szName.isEmpty()) appName = szName;
373 QString szLink;
374 if(bAllUser)
375 {
376 szLink = "/etc/xdg";
377 } else {
378 szLink = QStandardPaths::writableLocation(QStandardPaths::HomeLocation)
379 + "/.config";
380 }
381 szLink += "/autostart";
382 /*
383 * LINUX 应该有脚本 debian/postinst 建立好目录。
384 * 但是由于安装时是 root 用户。使用时是当前用户。
385 * 所以当前用户可能未正确建立。
386 */
387 QDir d(szLink);
388 if(!d.exists())
389 {
390 qWarning(log) << "Create directory" << szLink;
391 d.mkpath(szLink);
392 }
393 szLink += "/" + appName;
394 return szLink;
395}
396
397
398} //namespace RabbitCommon
static QString GetDesktopFileLink(const QString &szName=QString(), bool bAllUser=false)
GetDesktopFileLink.
static QString GetDesktopFileName(const QString &szPath=QString(), const QString &szName=QString())
Generate the name of desktop file.
static bool executeByRoot(const QString &program, const QStringList &arguments=QStringList())
executeByRoot: Run with administrator privileges