Restore the start menu shortcut as a proper launcher for the UI and service

This commit is contained in:
Cameron Gutman
2023-04-29 15:48:13 -05:00
parent 14fd7ad498
commit c4c04694ac
9 changed files with 373 additions and 46 deletions

View File

@@ -16,6 +16,10 @@
#include "platform/common.h"
#ifdef _WIN32
#include <shellapi.h>
#endif
namespace fs = std::filesystem;
using namespace std::literals;
@@ -1091,6 +1095,8 @@ namespace config {
int
parse(int argc, char *argv[]) {
std::unordered_map<std::string, std::string> cmd_vars;
bool shortcut_launch = false;
bool service_admin_launch = false;
for (auto x = 1; x < argc; ++x) {
auto line = argv[x];
@@ -1099,6 +1105,12 @@ namespace config {
print_help(*argv);
return 1;
}
else if (line == "--shortcut"sv) {
shortcut_launch = true;
}
else if (line == "--shortcut-admin"sv) {
service_admin_launch = true;
}
else if (*line == '-') {
if (*(line + 1) == '-') {
sunshine.cmd.name = line + 2;
@@ -1156,6 +1168,51 @@ namespace config {
apply_config(std::move(vars));
#ifdef _WIN32
// We have to wait until the config is loaded to handle these launches,
// because we need to have the correct base port loaded in our config.
if (service_admin_launch) {
// This is a relaunch as admin to start the service
service_ctrl::start_service();
// Always return 1 to ensure Sunshine doesn't start normally
return 1;
}
else if (shortcut_launch) {
if (!service_ctrl::is_service_running()) {
// If the service isn't running, relaunch ourselves as admin to start it
WCHAR executable[MAX_PATH];
GetModuleFileNameW(NULL, executable, ARRAYSIZE(executable));
SHELLEXECUTEINFOW shell_exec_info {};
shell_exec_info.cbSize = sizeof(shell_exec_info);
shell_exec_info.fMask = SEE_MASK_NOASYNC | SEE_MASK_NO_CONSOLE | SEE_MASK_NOCLOSEPROCESS;
shell_exec_info.lpVerb = L"runas";
shell_exec_info.lpFile = executable;
shell_exec_info.lpParameters = L"--shortcut-admin";
shell_exec_info.nShow = SW_NORMAL;
if (!ShellExecuteExW(&shell_exec_info)) {
auto winerr = GetLastError();
std::cout << "Error: ShellExecuteEx() failed:"sv << winerr << std::endl;
return 1;
}
// Wait for the elevated process to finish starting the service
WaitForSingleObject(shell_exec_info.hProcess, INFINITE);
CloseHandle(shell_exec_info.hProcess);
// Wait for the UI to be ready for connections
service_ctrl::wait_for_ui_ready();
}
// Launch the web UI
launch_ui();
// Always return 1 to ensure Sunshine doesn't start normally
return 1;
}
#endif
return 0;
}
} // namespace config