This commit is contained in:
crschnick
2025-01-20 16:12:14 +00:00
parent 407b649ae7
commit d59d087682
9 changed files with 70 additions and 16 deletions

View File

@@ -65,12 +65,12 @@ public interface ExternalEditorType extends PrefsChoiceValue {
@Override
protected Optional<Path> determineInstallation() {
var found =
WindowsRegistry.local().readValue(WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Notepad++", null);
WindowsRegistry.local().readStringValueIfPresent(WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Notepad++", null);
// Check 32 bit install
if (found.isEmpty()) {
found = WindowsRegistry.local()
.readValue(WindowsRegistry.HKEY_LOCAL_MACHINE, "WOW6432Node\\SOFTWARE\\Notepad++", null);
.readStringValueIfPresent(WindowsRegistry.HKEY_LOCAL_MACHINE, "WOW6432Node\\SOFTWARE\\Notepad++", null);
}
return found.map(p -> p + "\\notepad++.exe").map(Path::of);
}

View File

@@ -83,7 +83,7 @@ public interface ExternalRdpClientType extends PrefsChoiceValue {
protected Optional<Path> determineInstallation() {
try {
var r = WindowsRegistry.local()
.readValue(WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\rdm\\DefaultIcon");
.readStringValueIfPresent(WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\rdm\\DefaultIcon");
return r.map(Path::of);
} catch (Exception e) {
ErrorEvent.fromThrowable(e).omit().handle();

View File

@@ -26,7 +26,7 @@ public class MobaXTermTerminalType extends ExternalTerminalType.WindowsType {
protected Optional<Path> determineInstallation() {
try {
var r = WindowsRegistry.local()
.readValue(WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\mobaxterm\\DefaultIcon");
.readStringValueIfPresent(WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\mobaxterm\\DefaultIcon");
return r.map(Path::of);
} catch (Exception e) {
ErrorEvent.fromThrowable(e).omit().handle();

View File

@@ -91,7 +91,7 @@ public interface TabbyTerminalType extends ExternalTerminalType, TrackableTermin
@Override
protected Optional<Path> determineInstallation() {
var perUser = WindowsRegistry.local()
.readValue(
.readStringValueIfPresent(
WindowsRegistry.HKEY_CURRENT_USER,
"SOFTWARE\\71445fac-d6ef-5436-9da7-5a323762d7f5",
"InstallLocation")
@@ -102,7 +102,7 @@ public interface TabbyTerminalType extends ExternalTerminalType, TrackableTermin
}
var systemWide = WindowsRegistry.local()
.readValue(
.readStringValueIfPresent(
WindowsRegistry.HKEY_LOCAL_MACHINE,
"SOFTWARE\\71445fac-d6ef-5436-9da7-5a323762d7f5",
"InstallLocation")

View File

@@ -40,7 +40,7 @@ public class TermiusTerminalType implements ExternalTerminalType {
}
case OsType.Windows windows -> {
var r = WindowsRegistry.local()
.readValue(WindowsRegistry.HKEY_CURRENT_USER, "SOFTWARE\\Classes\\termius");
.readStringValueIfPresent(WindowsRegistry.HKEY_CURRENT_USER, "SOFTWARE\\Classes\\termius");
yield r.isPresent();
}
};

View File

@@ -63,7 +63,7 @@ public interface WezTerminalType extends ExternalTerminalType, TrackableTerminal
"http://wezfurlong.org/wezterm");
if (foundKey.isPresent()) {
var installKey = WindowsRegistry.local()
.readValue(foundKey.get().getHkey(), foundKey.get().getKey(), "InstallLocation");
.readStringValueIfPresent(foundKey.get().getHkey(), foundKey.get().getKey(), "InstallLocation");
if (installKey.isPresent()) {
return installKey.map(p -> p + "\\wezterm-gui.exe").map(Path::of);
}

View File

@@ -29,7 +29,7 @@ public class XShellTerminalType extends ExternalTerminalType.WindowsType {
protected Optional<Path> determineInstallation() {
try {
var r = WindowsRegistry.local()
.readValue(
.readStringValueIfPresent(
WindowsRegistry.HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\Xshell.exe");
return r.map(Path::of);

View File

@@ -8,7 +8,7 @@ import com.sun.jna.platform.win32.Advapi32Util;
import com.sun.jna.platform.win32.WinReg;
import lombok.Value;
import java.util.Optional;
import java.util.*;
public abstract class WindowsRegistry {
@@ -31,12 +31,16 @@ public abstract class WindowsRegistry {
public abstract boolean keyExists(int hkey, String key) throws Exception;
public abstract List<String> listSubKeys(int hkey, String key) throws Exception;
public abstract boolean valueExists(int hkey, String key, String valueName) throws Exception;
public abstract Optional<String> readValue(int hkey, String key, String valueName) throws Exception;
public abstract OptionalInt readIntegerValueIfPresent(int hkey, String key, String valueName) throws Exception;
public Optional<String> readValue(int hkey, String key) throws Exception {
return readValue(hkey, key, null);
public abstract Optional<String> readStringValueIfPresent(int hkey, String key, String valueName) throws Exception;
public Optional<String> readStringValueIfPresent(int hkey, String key) throws Exception {
return readStringValueIfPresent(hkey, key, null);
}
public abstract Optional<String> findValuesRecursive(int hkey, String key, String valueName) throws Exception;
@@ -61,6 +65,17 @@ public abstract class WindowsRegistry {
}
}
@Override
public List<String> listSubKeys(int hkey, String key) throws Exception {
// This can fail even with errors in case the jna native library extraction or loading fails
try {
return Arrays.asList(Advapi32Util.registryGetKeys(hkey(hkey), key));
} catch (Throwable t) {
ErrorEvent.fromThrowable(t).handle();
return List.of();
}
}
@Override
public boolean valueExists(int hkey, String key, String valueName) {
// This can fail even with errors in case the jna native library extraction or loading fails
@@ -73,7 +88,22 @@ public abstract class WindowsRegistry {
}
@Override
public Optional<String> readValue(int hkey, String key, String valueName) {
public OptionalInt readIntegerValueIfPresent(int hkey, String key, String valueName) throws Exception {
// This can fail even with errors in case the jna native library extraction or loading fails
try {
if (!Advapi32Util.registryValueExists(hkey(hkey), key, valueName)) {
return OptionalInt.empty();
}
return OptionalInt.of(Advapi32Util.registryGetIntValue(hkey(hkey), key, valueName));
} catch (Throwable t) {
ErrorEvent.fromThrowable(t).handle();
return OptionalInt.empty();
}
}
@Override
public Optional<String> readStringValueIfPresent(int hkey, String key, String valueName) {
// This can fail even with errors in case the jna native library extraction or loading fails
try {
if (!Advapi32Util.registryValueExists(hkey(hkey), key, valueName)) {
@@ -113,7 +143,7 @@ public abstract class WindowsRegistry {
}
if (original.contains(" ")) {
String[] parsed = original.split(" ");
String[] parsed = original.split(" {4}");
return Optional.of(parsed[parsed.length - 1]);
}
@@ -141,6 +171,18 @@ public abstract class WindowsRegistry {
}
}
@Override
public List<String> listSubKeys(int hkey, String key) throws Exception {
var prefix = hkey(hkey) + "\\";
var command = CommandBuilder.of()
.add("reg", "query")
.addQuoted(prefix + key);
var out = shellControl.command(command).readStdoutOrThrow();
return out.lines().filter(s -> {
return s.contains(prefix);
}).map(s -> s.replace(prefix, "")).toList();
}
@Override
public boolean valueExists(int hkey, String key, String valueName) throws Exception {
var command = CommandBuilder.of()
@@ -154,7 +196,17 @@ public abstract class WindowsRegistry {
}
@Override
public Optional<String> readValue(int hkey, String key, String valueName) throws Exception {
public OptionalInt readIntegerValueIfPresent(int hkey, String key, String valueName) throws Exception {
var r = readStringValueIfPresent(hkey, key, valueName);
if (r.isPresent()) {
return OptionalInt.of(Integer.parseInt(r.get()));
} else {
return OptionalInt.empty();
}
}
@Override
public Optional<String> readStringValueIfPresent(int hkey, String key, String valueName) throws Exception {
var command = CommandBuilder.of()
.add("reg", "query")
.addQuoted(hkey(hkey) + "\\" + key)

View File

@@ -1294,3 +1294,5 @@ identityName=Identity name
identityNameDescription=Give this identity a custom name
tailscaleTailnet.displayName=Tailnet
tailscaleTailnet.displayDescription=Connect to a specific tailnet with your account
puttyConnections=PuTTY connections
kittyConnections=KiTTY connections