UI: Service: Restart clients on upgrade

This commit is contained in:
Nodir Temirkhodjaev 2024-05-02 10:47:15 +03:00
parent 67e90b03e5
commit f95ab81d98
11 changed files with 42 additions and 32 deletions

View File

@ -17,7 +17,8 @@
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
SetupMutex=Global\{#APP_BASE}Setup
; Don't use AppMutex, and auto-restart the running instances
; Don't use AppMutex
RestartApplications=no
AppName={#APP_NAME}
AppVersion={#APP_VERSION_STR}
VersionInfoVersion={#APP_VERSION_STR}
@ -84,6 +85,7 @@ Name: "{commondesktop}\{#APP_NAME}"; Filename: "{#APP_EXE}"; WorkingDir: "{app}"
[Run]
; 1. Uninstall -> 2. Install Driver -> 3. Portable -> 4. Service
Filename: "{#APP_EXE}"; Parameters: "-u most"
Filename: "{app}\driver\scripts\reinstall.bat"; Parameters: {code:DriverInstallArgs}; \
@ -311,12 +313,11 @@ begin
Result := True;
end;
function StopFortService(var ResultCode: Integer): Boolean;
function StopFortService(): Boolean;
var
path: String;
ResultCode: Integer;
begin
ResultCode := -1;
path := ExpandConstant('{#APP_EXE}');
if not FileExists(path) then
@ -325,7 +326,7 @@ begin
Exit;
end;
Exec(path, '-s', '', SW_SHOW, ewWaitUntilTerminated, ResultCode)
Exec(path, '-s', '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
Result := (ResultCode = 0);
end;
@ -446,15 +447,8 @@ begin
end;
function PrepareToInstall(var NeedsRestart: Boolean): String;
var
ResultCode: Integer;
begin
if Exec('sc.exe', ExpandConstant('stop {#APP_SVC_NAME}'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then
begin
if ResultCode <> 0 then StopFortService(ResultCode);
if ResultCode = 0 then Sleep(100); // Let the service to stop
end;
StopFortService();
Result := '';
end;

View File

@ -1 +1 @@
@for %%f in (FortFirewall-*.exe) do @call .\%%f /SILENT /LAUNCH
@for %%f in (FortFirewall-*.exe) do @call .\%%f /SILENT

View File

@ -428,6 +428,7 @@ HEADERS += \
util/osutil.h \
util/processinfo.h \
util/regkey.h \
util/service/service_types.h \
util/service/servicehandle.h \
util/service/serviceinfo.h \
util/service/servicelistmonitor.h \

View File

@ -6,6 +6,7 @@
#include <QTimer>
#include <fortsettings.h>
#include <manager/servicemanager.h>
#include <rpc/rpcmanager.h>
#include <task/taskinfoupdatechecker.h>
#include <task/taskmanager.h>
@ -80,11 +81,13 @@ void AutoUpdateManager::setupManager()
void AutoUpdateManager::setupRestart()
{
if (IoC<FortSettings>()->isService())
return;
if (!OsUtil::registerAppRestart()) {
qCWarning(LC) << "Restart registration error";
if (IoC<FortSettings>()->isService()) {
connect(IoC<ServiceManager>(), &ServiceManager::stopRestartingRequested, this,
&AutoUpdateManager::restartClients);
} else {
if (!OsUtil::registerAppRestart()) {
qCWarning(LC) << "Restart registration error";
}
}
}

View File

@ -11,6 +11,7 @@
#include <control/controlmanager.h>
#include <util/ioc/ioccontainer.h>
#include <util/osutil.h>
#include <util/service/service_types.h>
#include <util/startuputil.h>
namespace {
@ -106,14 +107,14 @@ void ServiceManager::processControl(quint32 code, quint32 eventType)
state = SERVICE_RUNNING;
} break;
case SERVICE_CONTROL_STOP: {
if (!acceptStop())
break;
state = acceptStop() ? SERVICE_STOP_PENDING : 0;
} break;
case ServiceControlStopRestarting: {
emit stopRestartingRequested();
}
Q_FALLTHROUGH();
case FORT_SERVICE_CONTROL_UNINSTALL:
case ServiceControlStop:
case SERVICE_CONTROL_SHUTDOWN: {
OsUtil::quit("service control"); // it's threadsafe
state = SERVICE_STOP_PENDING;
} break;
case SERVICE_CONTROL_DEVICEEVENT: {
@ -123,6 +124,10 @@ void ServiceManager::processControl(quint32 code, quint32 eventType)
} break;
}
if (state == SERVICE_STOP_PENDING) {
OsUtil::quit("service control"); // it's threadsafe
}
reportStatus(state);
}

View File

@ -34,6 +34,7 @@ public:
signals:
void pauseRequested();
void continueRequested();
void stopRestartingRequested();
void driveListChanged();
protected:

View File

@ -0,0 +1,9 @@
#ifndef SERVICE_TYPES_H
#define SERVICE_TYPES_H
enum ServiceControlCode {
ServiceControlStop = 128,
ServiceControlStopRestarting,
};
#endif // SERVICE_TYPES_H

View File

@ -5,6 +5,7 @@
#define WIN32_LEAN_AND_MEAN
#include <qt_windows.h>
#include "service_types.h"
#include "servicemanageriface.h"
ServiceHandle::ServiceHandle(
@ -32,7 +33,7 @@ bool ServiceHandle::startService()
return StartServiceW(SC_HANDLE(m_serviceHandle), 0, nullptr);
}
bool ServiceHandle::stopService()
bool ServiceHandle::stopService(bool restarting)
{
int n = 3; /* count of attempts to stop the service */
do {
@ -41,9 +42,7 @@ bool ServiceHandle::stopService()
&& status.dwCurrentState == SERVICE_STOPPED)
return true;
const DWORD controlCode = (status.dwControlsAccepted & SERVICE_ACCEPT_STOP) != 0
? SERVICE_CONTROL_STOP
: FORT_SERVICE_CONTROL_UNINSTALL;
const DWORD controlCode = restarting ? ServiceControlStopRestarting : ServiceControlStop;
ControlService(SC_HANDLE(m_serviceHandle), controlCode, &status);

View File

@ -26,7 +26,7 @@ public:
bool queryIsRunning();
bool startService();
bool stopService();
bool stopService(bool restarting = false);
bool createService(const CreateServiceArg &csa);
bool deleteService();

View File

@ -3,8 +3,6 @@
#include <QObject>
#define FORT_SERVICE_CONTROL_UNINSTALL 128
class ServiceManagerIface
{
public:

View File

@ -179,7 +179,7 @@ bool StartupUtil::stopService()
{
ServiceHandle svc(serviceNameStr, SC_MANAGER_ALL_ACCESS, SERVICE_ALL_ACCESS);
if (svc.isServiceOpened()) {
return svc.stopService();
return svc.stopService(/*restarting=*/true);
}
return false;