• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

devonfw / IDEasy / 27560619134

15 Jun 2026 04:25PM UTC coverage: 71.102% (+0.05%) from 71.057%
27560619134

push

github

web-flow
#1991: improve windows helper mock (#2020)

4540 of 7078 branches covered (64.14%)

Branch coverage included in aggregate %.

11785 of 15882 relevant lines covered (74.2%)

3.14 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

73.53
cli/src/main/java/com/devonfw/tools/ide/os/WindowsHelperImpl.java
1
package com.devonfw.tools.ide.os;
2

3
import java.util.List;
4

5
import org.slf4j.Logger;
6
import org.slf4j.LoggerFactory;
7

8
import com.devonfw.tools.ide.context.IdeContext;
9
import com.devonfw.tools.ide.log.IdeLogLevel;
10
import com.devonfw.tools.ide.process.ProcessErrorHandling;
11
import com.devonfw.tools.ide.process.ProcessMode;
12
import com.devonfw.tools.ide.process.ProcessResult;
13

14
/**
15
 * Implementation of {@link WindowsHelper}.
16
 */
17
public class WindowsHelperImpl implements WindowsHelper {
18

19
  private static final Logger LOG = LoggerFactory.getLogger(WindowsHelperImpl.class);
3✔
20

21
  /** Registry key for the users environment variables. */
22
  public static final String HKCU_ENVIRONMENT = "HKCU\\Environment";
23

24
  /** Common Windows registry base paths containing (uninstall) information for installed applications (system-wide and per-user). */
25
  private static final String[] REGISTRY_BASE_PATHS = {
16✔
26
      "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall",
27
      "HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall",
28
      "HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
29
  };
30

31
  private final IdeContext context;
32

33
  /**
34
   * The constructor.
35
   *
36
   * @param context the {@link IdeContext}.
37
   */
38
  public WindowsHelperImpl(IdeContext context) {
2✔
39

40
    this.context = context;
3✔
41
  }
1✔
42

43
  @Override
44
  public void setUserEnvironmentValue(String key, String value) {
45

46
    ProcessResult result = this.context.newProcess().executable("setx").addArgs(key, value).run(ProcessMode.DEFAULT_SILENT);
×
47
    assert (result.isSuccessful());
×
48
  }
×
49

50
  @Override
51
  public void removeUserEnvironmentValue(String key) {
52
    ProcessResult result = this.context.newProcess().executable("reg").addArgs("delete", HKCU_ENVIRONMENT, "/v", key, "/f")
×
53
        .errorHandling(ProcessErrorHandling.LOG_WARNING).run(ProcessMode.DEFAULT_CAPTURE);
×
54
    if (result.isSuccessful()) {
×
55
      LOG.debug("Removed environment variable {}", key);
×
56
    } else {
57
      result.log(IdeLogLevel.WARNING);
×
58
    }
59
  }
×
60

61
  @Override
62
  public String getUserEnvironmentValue(String key) {
63

64
    return getRegistryValue(HKCU_ENVIRONMENT, key);
5✔
65
  }
66

67
  @Override
68
  public String getRegistryValue(String path, String key) {
69

70
    List<String> out = runReg("query", path, "/v", key);
21✔
71
    if (out != null) {
2✔
72
      return retrieveRegString(key, out);
5✔
73
    }
74
    return null;
2✔
75
  }
76

77
  @Override
78
  public WindowsAppInstallation getAppInstallationFromRegistry(String appName) {
79
    String uninstallKey = findUninstallKey(appName);
4✔
80
    if (uninstallKey == null) {
2✔
81
      return null;
2✔
82
    }
83

84
    List<String> out = runReg("query", uninstallKey);
13✔
85
    if (out == null) {
2✔
86
      return null;
2✔
87
    }
88

89
    String version = retrieveRegString("DisplayVersion", out);
5✔
90
    String icon = retrieveRegString("DisplayIcon", out);
5✔
91
    String uninstallString = retrieveRegString("UninstallString", out);
5✔
92
    String installLocation = retrieveRegString("InstallLocation", out);
5✔
93

94
    return new WindowsAppInstallation(version, icon, uninstallString, installLocation);
8✔
95
  }
96

97
  private String findUninstallKey(String appName) {
98

99
    for (String registryBasePath : REGISTRY_BASE_PATHS) {
16✔
100
      List<String> out = runReg("query", registryBasePath, "/s", "/f", appName);
25✔
101
      if (out == null) {
2!
102
        continue;
×
103
      }
104
      for (String line : out) {
10✔
105
        line = line.trim();
3✔
106
        if (line.startsWith("HKEY_")) {
4✔
107
          return line; // exact registry path (key) for tool
2✔
108
        }
109
      }
1✔
110
    }
111
    return null;
2✔
112

113
  }
114

115
  /**
116
   * Executes a Windows registry command and returns its output.
117
   *
118
   * @param args the registry command arguments.
119
   * @return the command output lines, or {@code null} if the command failed
120
   */
121
  protected List<String> runReg(String... args) {
122
    ProcessResult result = this.context.newProcess()
×
123
        .errorHandling(ProcessErrorHandling.LOG_WARNING)
×
124
        .executable("reg")
×
125
        .addArgs(args)
×
126
        .run(ProcessMode.DEFAULT_CAPTURE);
×
127
    if (!result.isSuccessful()) {
×
128
      return null;
×
129
    }
130
    return result.getOut();
×
131
  }
132

133
  /**
134
   * Parses the result of a registry query and outputs the given key.
135
   *
136
   * @param key the key to look for.
137
   * @param out List of keys from registry query result.
138
   * @return the registry value.
139
   */
140
  protected String retrieveRegString(String key, List<String> out) {
141
    for (String line : out) {
10✔
142
      int i = line.indexOf(key);
4✔
143
      if (i >= 0) {
2✔
144
        assert (i == 4);
4!
145
        i += key.length();
5✔
146
        i = skipWhitespaces(line, i);
4✔
147
        i = skipNonWhitespaces(line, i); // the type (e.g. "REG_SZ")
4✔
148
        i = skipWhitespaces(line, i);
4✔
149
        line = line.substring(i);
4✔
150
        return line;
2✔
151
      }
152
    }
1✔
153
    return null;
2✔
154
  }
155

156
  private static int skipWhitespaces(String string, int i) {
157

158
    int len = string.length();
3✔
159
    while ((i < len) && Character.isWhitespace(string.charAt(i))) {
8✔
160
      i++;
2✔
161
    }
162
    return i;
2✔
163
  }
164

165
  private static int skipNonWhitespaces(String string, int i) {
166

167
    int len = string.length();
3✔
168
    while ((i < len) && !Character.isWhitespace(string.charAt(i))) {
8!
169
      i++;
2✔
170
    }
171
    return i;
2✔
172
  }
173

174
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc