NSIS manual: > /D sets the default installation directory ($INSTDIR), overriding InstallDir > and InstallDirRegKey. It must be the last parameter used in the command line > and must not contain any quotes, even if the path contains spaces. Only > absolute paths are supported.
(
installer,
install_dir,
installer_input=None,
timeout=420,
check=True,
options: list | None = None,
)
| 174 | |
| 175 | |
| 176 | def _run_installer_exe( |
| 177 | installer, |
| 178 | install_dir, |
| 179 | installer_input=None, |
| 180 | timeout=420, |
| 181 | check=True, |
| 182 | options: list | None = None, |
| 183 | ): |
| 184 | """ |
| 185 | NSIS manual: |
| 186 | > /D sets the default installation directory ($INSTDIR), overriding InstallDir |
| 187 | > and InstallDirRegKey. It must be the last parameter used in the command line |
| 188 | > and must not contain any quotes, even if the path contains spaces. Only |
| 189 | > absolute paths are supported. |
| 190 | Since subprocess.Popen WILL escape the spaces with quotes, we need to provide |
| 191 | them as separate arguments. We don't care about multiple spaces collapsing into |
| 192 | one, since the point is to just have spaces in the installation path -- one |
| 193 | would be enough too :) |
| 194 | This is why we have this weird .split() thingy down there in `/D=...`. |
| 195 | |
| 196 | Note that we do print information to the console, but that's not the stdout stream |
| 197 | of the subprocess. We make NSIS attach itself to the parent console and write directly there. |
| 198 | As a result we can't capture the output, so we still have to rely on the logfiles. |
| 199 | """ |
| 200 | if not sys.platform.startswith("win"): |
| 201 | raise ValueError("Can only run .exe installers on Windows") |
| 202 | if "NSIS_USING_LOG_BUILD" not in os.environ: |
| 203 | warnings.warn( |
| 204 | "Windows installers are tested with NSIS in silent mode, which does " |
| 205 | "not report errors to stdout. You should use logging-enabled NSIS builds " |
| 206 | "to generate an 'install.log' file this script will search for errors " |
| 207 | "after completion." |
| 208 | ) |
| 209 | options = options or [] |
| 210 | cmd = [ |
| 211 | "cmd.exe", |
| 212 | "/c", |
| 213 | "start", |
| 214 | "/wait", |
| 215 | installer, |
| 216 | "/S", |
| 217 | *options, |
| 218 | *f"/D={install_dir}".split(), |
| 219 | ] |
| 220 | process = _execute(cmd, installer_input=installer_input, timeout=timeout, check=check) |
| 221 | if check: |
| 222 | _check_installer_log(install_dir) |
| 223 | return process |
| 224 | |
| 225 | |
| 226 | def _run_uninstaller_exe( |
no test coverage detected