diff options
| author | Dan Engelbrecht <[email protected]> | 2025-01-08 13:49:56 +0100 |
|---|---|---|
| committer | Dan Engelbrecht <[email protected]> | 2025-01-08 13:49:56 +0100 |
| commit | 995aec217bbb26c9c2a701cc77edb067ffbf8d36 (patch) | |
| tree | 2da2d3fd806547bd9f38bc190514abbf9fdb6361 /src/zen/cmds/service_cmd.cpp | |
| parent | check if service is already installed before attempting install (diff) | |
| download | archived-zen-995aec217bbb26c9c2a701cc77edb067ffbf8d36.tar.xz archived-zen-995aec217bbb26c9c2a701cc77edb067ffbf8d36.zip | |
add ServiceLevel for service processes: User, AllUsers and Service
Diffstat (limited to 'src/zen/cmds/service_cmd.cpp')
| -rw-r--r-- | src/zen/cmds/service_cmd.cpp | 129 |
1 files changed, 103 insertions, 26 deletions
diff --git a/src/zen/cmds/service_cmd.cpp b/src/zen/cmds/service_cmd.cpp index aede68573..7727ed8a2 100644 --- a/src/zen/cmds/service_cmd.cpp +++ b/src/zen/cmds/service_cmd.cpp @@ -120,6 +120,12 @@ ServiceCommand::ServiceCommand() m_StatusOptions.positional_help("name"); m_InstallOptions.add_options()("h,help", "Print help"); + m_InstallOptions.add_option("", + "l", + "service-level", + "Service level: CurrentUser, AllUsers, System. Default is CurrentUser", + cxxopts::value(m_ServiceLevel), + "<level>"); m_InstallOptions.add_option("", "s", "executable", "Path to server executable", cxxopts::value(m_ServerExecutable), "<path>"); m_InstallOptions.add_option("", "n", @@ -209,19 +215,29 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) ZEN_CONSOLE("Can't get information about service '{}'. Reason: '{}'", m_ServiceName, Ec.message()); return 1; } - ZEN_CONSOLE( - "Service '{}':\n" - " Status: {}\n" - " Executable: {}\n" - " CommandLineOptions: {}\n" - " Display Name: {}\n" - " Description: {}", - m_ServiceName, - ToString(Info.Status), - Info.Spec.ExecutablePath, - Info.Spec.CommandLineOptions, - Info.Spec.DisplayName, - Info.Spec.Description); + if (Info.Status == ServiceStatus::NotInstalled) + { + ZEN_CONSOLE("Service '{}' is not installed", m_ServiceName); + return 0; + } + else + { + ZEN_CONSOLE( + "Service '{}':\n" + " Status: {}\n" + " Level: {}\n" + " Executable: {}\n" + " CommandLineOptions: {}\n" + " Display Name: {}\n" + " Description: {}", + m_ServiceName, + ToString(Info.Status), + ToString(Info.Spec.ServiceLevel), + Info.Spec.ExecutablePath, + Info.Spec.CommandLineOptions, + Info.Spec.DisplayName, + Info.Spec.Description); + } } if (SubOption == &m_InstallOptions) @@ -233,12 +249,14 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) ZEN_CONSOLE( "Service '{}' already installed:\n" " Status: {}\n" + " Level: {}\n" " Executable: {}\n" " CommandLineOptions: {}\n" " Display Name: {}\n" " Description: {}", m_ServiceName, ToString(Info.Status), + ToString(Info.Spec.ServiceLevel), Info.Spec.ExecutablePath, Info.Spec.CommandLineOptions, Info.Spec.DisplayName, @@ -246,8 +264,18 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) return 1; } + std::optional<ServiceLevel> Level = ServiceLevel::CurrentUser; + if (!m_ServiceLevel.empty()) + { + Level = FromString(m_ServiceLevel); + } + if (!Level.has_value()) + { + throw zen::OptionParseException("invalid service level"); + } + #if ZEN_PLATFORM_WINDOWS - if (!WinIsElevated()) + if (!WinIsElevated() && (Level.value() != ServiceLevel::CurrentUser)) { return WinRelaunchElevated(); } @@ -259,12 +287,12 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) m_ServerExecutable = ExePath; } m_ServerExecutable = std::filesystem::absolute(m_ServerExecutable); - - Ec = InstallService(m_ServiceName, - ServiceSpec{.ExecutablePath = m_ServerExecutable, - .CommandLineOptions = GlobalOptions.PassthroughCommandLine, - .DisplayName = m_ServiceDisplayName, - .Description = m_ServiceDescription}); + Ec = InstallService(m_ServiceName, + ServiceSpec{.ServiceLevel = Level.value(), + .ExecutablePath = m_ServerExecutable, + .CommandLineOptions = GlobalOptions.PassthroughCommandLine, + .DisplayName = m_ServiceDisplayName, + .Description = m_ServiceDescription}); if (Ec) { ZEN_CONSOLE("Failed to install service '{}' using '{}' . Reason: '{}'", m_ServiceName, m_ServerExecutable, Ec.message()); @@ -275,13 +303,26 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) if (SubOption == &m_UninstallOptions) { + ServiceInfo Info; + std::error_code Ec = QueryInstalledService(m_ServiceName, Info); + if (Ec) + { + ZEN_CONSOLE("Failed to inspect installed service '{}'. Reason: '{}'", m_ServiceName, Ec.message()); + return 1; + } + if (Info.Status == ServiceStatus::NotInstalled) + { + ZEN_CONSOLE("Service '{}' is not installed", m_ServiceName); + return 0; + } + #if ZEN_PLATFORM_WINDOWS - if (!WinIsElevated()) + if (!WinIsElevated() && (Info.Spec.ServiceLevel != ServiceLevel::CurrentUser)) { return WinRelaunchElevated(); } #endif // ZEN_PLATFORM_WINDOWS - std::error_code Ec = UninstallService(m_ServiceName); + Ec = UninstallService(m_ServiceName, Info.Spec.ServiceLevel); if (Ec) { ZEN_CONSOLE("Failed to uninstall service '{}'. Reason: '{}'", m_ServiceName, Ec.message()); @@ -292,13 +333,31 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) if (SubOption == &m_StartOptions) { + ServiceInfo Info; + std::error_code Ec = QueryInstalledService(m_ServiceName, Info); + if (Ec) + { + ZEN_CONSOLE("Failed to inspect installed service '{}'. Reason: '{}'", m_ServiceName, Ec.message()); + return 1; + } + if (Info.Status == ServiceStatus::NotInstalled) + { + ZEN_CONSOLE("Service '{}' is not installed", m_ServiceName); + return 1; + } + if (Info.Status != ServiceStatus::Stopped) + { + ZEN_CONSOLE("Service '{}' is already running", m_ServiceName); + return 1; + } + #if ZEN_PLATFORM_WINDOWS - if (!WinIsElevated()) + if (!WinIsElevated() && (Info.Spec.ServiceLevel != ServiceLevel::CurrentUser)) { return WinRelaunchElevated(); } #endif // ZEN_PLATFORM_WINDOWS - std::error_code Ec = StartService(m_ServiceName); + Ec = StartService(m_ServiceName, Info.Spec.ServiceLevel); if (Ec) { ZEN_CONSOLE("Failed to start service '{}'. Reason: '{}'", m_ServiceName, Ec.message()); @@ -309,13 +368,31 @@ ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) if (SubOption == &m_StopOptions) { + ServiceInfo Info; + std::error_code Ec = QueryInstalledService(m_ServiceName, Info); + if (Ec) + { + ZEN_CONSOLE("Failed to inspect installed service '{}'. Reason: '{}'", m_ServiceName, Ec.message()); + return 1; + } + if (Info.Status == ServiceStatus::NotInstalled) + { + ZEN_CONSOLE("Service '{}' is not installed", m_ServiceName); + return 1; + } + if (Info.Status != ServiceStatus::Running) + { + ZEN_CONSOLE("Service '{}' is not running", m_ServiceName); + return 1; + } + #if ZEN_PLATFORM_WINDOWS - if (!WinIsElevated()) + if (!WinIsElevated() && (Info.Spec.ServiceLevel != ServiceLevel::CurrentUser)) { return WinRelaunchElevated(); } #endif // ZEN_PLATFORM_WINDOWS - std::error_code Ec = StopService(m_ServiceName); + Ec = StopService(m_ServiceName, Info.Spec.ServiceLevel); if (Ec) { ZEN_CONSOLE("Failed to stop service '{}'. Reason: '{}'", m_ServiceName, Ec.message()); |