UI: Fix service stopping on uninstall with "Disable Service controls" option

This commit is contained in:
Nodir Temirkhodjaev 2023-03-11 12:11:27 +03:00
parent a3f1b1a86c
commit dac55059b5
4 changed files with 32 additions and 15 deletions

View File

@ -174,7 +174,7 @@ begin
if Form.ShowModal() = mrOk then
begin
Result := GetSHA1OfString(PwdEdit.Text);
Result := PwdEdit.Text;
end;
finally
Form.Free();
@ -194,7 +194,7 @@ begin
Exit;
end;
if AskPassword() <> passwordHash then
if GetSHA1OfString(AskPassword()) <> passwordHash then
begin
SuppressibleMsgBox('Wrong password', mbError, MB_OK, IDOK);
@ -218,16 +218,17 @@ begin
Result := CheckPasswordHash();
end;
function InitializeUninstall(): Boolean;
begin
Result := CheckPasswordHash();
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
if ResultCode = 0 then Sleep(100); // Let the service to stop
Result := '';
end;
function InitializeUninstall(): Boolean;
begin
Result := CheckPasswordHash();
end;

View File

@ -97,6 +97,7 @@ void ServiceManager::processControl(quint32 code)
break;
Q_FALLTHROUGH();
case FORT_SERVICE_CONTROL_UNINSTALL:
case SERVICE_CONTROL_SHUTDOWN: {
qCDebug(LC) << "Quit due service control";

View File

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

View File

@ -11,6 +11,7 @@
#include "fileutil.h"
#include "regkey.h"
#include "service/servicemanageriface.h"
namespace {
@ -134,6 +135,24 @@ bool installService(const wchar_t *serviceName, const wchar_t *serviceDisplay,
return res;
}
void stopService(SC_HANDLE svc)
{
int n = 3; /* count of attempts to stop the service */
do {
SERVICE_STATUS status;
if (QueryServiceStatus(svc, &status) && status.dwCurrentState == SERVICE_STOPPED)
break;
const DWORD controlCode = (status.dwControlsAccepted & SERVICE_ACCEPT_STOP) != 0
? SERVICE_CONTROL_STOP
: FORT_SERVICE_CONTROL_UNINSTALL;
ControlService(svc, controlCode, &status);
QThread::msleep(n * 100);
} while (--n > 0);
}
bool uninstallService(const wchar_t *serviceName)
{
bool res = false;
@ -141,14 +160,8 @@ bool uninstallService(const wchar_t *serviceName)
if (mngr) {
const SC_HANDLE svc = OpenServiceW(mngr, serviceName, SERVICE_ALL_ACCESS | DELETE);
if (svc) {
int n = 3; /* count of attempts to stop the service */
do {
SERVICE_STATUS status;
if (QueryServiceStatus(svc, &status) && status.dwCurrentState == SERVICE_STOPPED)
break;
ControlService(svc, SERVICE_CONTROL_STOP, &status);
QThread::msleep(n * 100);
} while (--n > 0);
stopService(svc);
res = DeleteService(svc);
CloseServiceHandle(svc);
}