Skip to content

Commit

Permalink
Fix registration, running and removal
Browse files Browse the repository at this point in the history
  • Loading branch information
tresf committed Sep 14, 2021
1 parent 1714d5c commit 4b429df
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 23 deletions.
9 changes: 8 additions & 1 deletion ant/windows/windows-launcher.nsi.in
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,14 @@ Section
StrCpy $command '"$R2" /s /k "$command"'
${EndIf}

Exec $command
; Check for "--wait" parameter
${StrLoc} $R3 "$params" "--wait" "<"
${If} $R3 != ""
ExecWait $command
${Else}
Exec $command
${EndIf}

${If} ${RunningX64}
${EnableX64FSRedirection}
${EndIf}
Expand Down
4 changes: 2 additions & 2 deletions src/qz/installer/Installer.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,11 @@ public static boolean preinstall() {
public static void install() throws Exception {
getInstance();
log.info("Installing to {}", instance.getDestination());
instance.removeLibs()
instance.removeServiceRegistration()
.removeLibs()
.deployApp()
.removeLegacyStartup()
.removeLegacyFiles()
.removeServiceRegistration()
.addSharedDirectory()
.addAppLauncher()
.addStartupEntry()
Expand Down
47 changes: 30 additions & 17 deletions src/qz/installer/WindowsInstaller.java
Original file line number Diff line number Diff line change
Expand Up @@ -206,22 +206,28 @@ public void spawn(List<String> args) throws Exception {

@Override
public Installer addServiceRegistration(String user) {
log.warn("Registering system service: {}", PROPS_FILE);
if(!SystemUtilities.isAdmin()) {
throw new UnsupportedOperationException("Installing a service requires elevation");
}

if(WindowsUtilities.serviceExists(PROPS_FILE)) {
log.warn("System service is already registered, removing.");
removeServiceRegistration();
}

Path nssm = SystemUtilities.getJarParentPath().resolve("utils/nssm.exe");
Path qz = SystemUtilities.getJarParentPath().resolve(PROPS_FILE + ".exe");
String servicePath = String.format("\"" + qz.toString() + "\" %s %s %s",
ArgValue.WAIT.getMatches()[0],
ArgValue.STEAL.getMatches()[0],
ArgValue.HEADLESS.getMatches()[0]);

// Install the service
if(ShellUtilities.execute(nssm.toString(), "install", PROPS_FILE, servicePath)) {
ShellUtilities.execute(nssm.toString(), "set", "DisplayName", ABOUT_TITLE);
ShellUtilities.execute(nssm.toString(), "set", "Description", ABOUT_DESCRIPTION);
ShellUtilities.execute(nssm.toString(), "set", "DependOnService", "Spooler");
if(ShellUtilities.execute(nssm.toString(), "install", PROPS_FILE,
qz.toString(),
ArgValue.WAIT.getMatches()[0],
ArgValue.STEAL.getMatches()[0],
ArgValue.HEADLESS.getMatches()[0])) {
ShellUtilities.execute(nssm.toString(), "set", PROPS_FILE, "DisplayName", ABOUT_TITLE);
ShellUtilities.execute(nssm.toString(), "set", PROPS_FILE, "Description", ABOUT_DESCRIPTION);
ShellUtilities.execute(nssm.toString(), "set", PROPS_FILE, "DependOnService", "Spooler");
log.info("Successfully registered system service: {}", PROPS_FILE);
if(user != null && !user.trim().isEmpty()) {
log.info("Setting service to run as {}", user);
Expand All @@ -233,7 +239,9 @@ public Installer addServiceRegistration(String user) {
TaskKiller.killAll();
// Instruct autostart to be ignored
FileUtilities.disableGlobalAutoStart();
log.info("Starting system service: {}", PROPS_FILE);
if(WindowsUtilities.startService(PROPS_FILE)) {
log.info("System system service started successfully.", PROPS_FILE);
return this;
}
}
Expand All @@ -242,20 +250,25 @@ public Installer addServiceRegistration(String user) {

@Override
public Installer removeServiceRegistration() {
log.info("Removing system service: {}", PROPS_FILE);
if(!SystemUtilities.isAdmin()) {
throw new UnsupportedOperationException("Removing a service requires elevation");
}

WindowsUtilities.stopService(PROPS_FILE);
Path nssm = SystemUtilities.getJarParentPath().resolve("utils/nssm.exe");
if(ShellUtilities.execute(nssm.toString(), "remove", PROPS_FILE, "confirm")) {
// Old tutorials used "QZ Tray" as the service name
ShellUtilities.execute(nssm.toString(), "remove", ABOUT_TITLE, "confirm");
// Restore default autostart settings by deleting the preference file
FileUtils.deleteQuietly(FileUtilities.SHARED_DIR.resolve(AUTOSTART_FILE).toFile());
log.info("System service successfully removed: {}", PROPS_FILE);
if(WindowsUtilities.serviceExists(PROPS_FILE)) {
WindowsUtilities.stopService(PROPS_FILE);
Path nssm = SystemUtilities.getJarParentPath().resolve("utils/nssm.exe");
if(ShellUtilities.execute(nssm.toString(), "remove", PROPS_FILE, "confirm")) {
// Old tutorials used "QZ Tray" as the service name
ShellUtilities.execute(nssm.toString(), "remove", ABOUT_TITLE, "confirm");
// Restore default autostart settings by deleting the preference file
FileUtils.deleteQuietly(FileUtilities.SHARED_DIR.resolve(AUTOSTART_FILE).toFile());
log.info("System service successfully removed: {}", PROPS_FILE);
} else {
log.error("An error occurred removing system service: {}", PROPS_FILE);
}
} else {
log.error("An error occurred removing system service: {}, please try to remove manually using 'sc ", PROPS_FILE);
log.info("System service was not found, skipping.");
}

return this;
Expand Down
6 changes: 5 additions & 1 deletion src/qz/utils/ArgParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,11 @@ public ExitStatus processInstallerArgs(ArgValue argValue, List<String> args) {
Installer.uninstall();
return SUCCESS;
case SERVICE:
Installer.getInstance().addServiceRegistration(valueOf(RUNAS));
if(hasFlag(REMOVE)) {
Installer.getInstance().removeServiceRegistration();
} else {
Installer.getInstance().addServiceRegistration(valueOf(RUNAS));
}
return SUCCESS;
case SPAWN:
args.remove(0); // first argument is "spawn", remove it
Expand Down
4 changes: 3 additions & 1 deletion src/qz/utils/ArgValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,9 @@ public enum ArgValueOption {

// service
RUNAS(ArgValue.SERVICE, "Username to run the system service as (Windows only)",
"--runas", "--user", "-u");
"--runas", "--user", "-u"),
REMOVE(ArgValue.SERVICE, "Remove the system service as (Windows only)",
"--remove", "-r");

ArgValue parent;
String description;
Expand Down
2 changes: 1 addition & 1 deletion src/qz/utils/FileUtilities.java
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ public static Path inheritParentPermissions(Path filePath) {
public static boolean disableGlobalAutoStart() {
Path autostart = SHARED_DIR.resolve(AUTOSTART_FILE);
try {
Files.write(autostart, "0".getBytes(StandardCharsets.UTF_8), StandardOpenOption.TRUNCATE_EXISTING);
Files.write(autostart, "0".getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE_NEW, StandardOpenOption.TRUNCATE_EXISTING);
return true;
}
catch(IOException e) {
Expand Down
12 changes: 12 additions & 0 deletions src/qz/utils/WindowsUtilities.java
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,18 @@ public static boolean isWow64() {
return isWow64;
}

public static boolean serviceExists(String serviceName) {
try {
W32ServiceManager serviceManager = new W32ServiceManager();
serviceManager.open(Winsvc.SC_MANAGER_ALL_ACCESS);
W32Service service = serviceManager.openService(serviceName, Winsvc.SC_MANAGER_ALL_ACCESS);
return true;
} catch(Win32Exception e) {
return false;
} catch(Throwable t) {}
return ShellUtilities.execute("sc", "query", serviceName);
}

public static boolean stopService(String serviceName) {
try {
W32ServiceManager serviceManager = new W32ServiceManager();
Expand Down

0 comments on commit 4b429df

Please sign in to comment.