beeradmoore/dlss-swapper · error · Exception

Could not launch installer

Error message

Could not launch installer

What it means

After downloading the installer to a temp file, DownloadAndInstallAsync launches it with Process.Start using UseShellExecute = true. Process.Start returning null means Windows could not start the installer process, so the updater throws instead of exiting the app and leaving the user with a silent failure.

Solutions

  1. Check antivirus quarantine logs and whitelist the downloaded installer; re-run the update.
  2. Verify the temp download file exists and is a valid executable (check size/signature) before Process.Start.
  3. Ensure no other process has locked the temp file; reboot and retry the update.
  4. Manually download the installer from the GitHub releases page and run it yourself.

Example fix

// before
var installerProcess = Process.Start(processStartInfo);
if (installerProcess is null)
    throw new Exception("Could not launch installer");
// after
if (File.Exists(tempDownloadFile) == false)
    throw new Exception($"Installer not found at {tempDownloadFile}");
var installerProcess = Process.Start(processStartInfo);
if (installerProcess is null)
    throw new Exception($"Could not launch installer at {tempDownloadFile}. It may be blocked by antivirus.");
Defensive patterns

Strategy: validation

Validate before calling

// Verify the installer exists and is non-trivially sized before launching
if (File.Exists(tempDownloadFile) == false || new FileInfo(tempDownloadFile).Length < 1024)
{
    // don't attempt Process.Start; treat as failed download
}

Type guard

bool CanLaunchInstaller(string path) => File.Exists(path) && new FileInfo(path).Length > 0;

Try / catch

try
{
    await updater.DownloadAndInstallAsync();
}
catch (Exception ex) when (ex.Message == "Could not launch installer")
{
    logger.LogWarning(ex, "Installer launch blocked; suggest manual install");
    // show dialog linking to the GitHub releases page
}

Prevention

When it happens

Trigger: Process.Start(processStartInfo) returns null: the temp installer file is missing or locked, the file association for .exe is broken, security software blocks execution of the downloaded file, or the temp path contains characters the shell cannot resolve.

Common situations: Antivirus (Defender or third-party) quarantining the downloaded installer, the temp file deleted between download and launch, corrupted download producing an invalid executable, or running in an environment (e.g. service context) where ShellExecute cannot resolve the handler.

Related errors


AI-assisted analysis of beeradmoore/dlss-swapper@ab9b1e2d4b (2026-09-15). Data as JSON: /api/errors/ea8624e881fe32b5. Report an issue: GitHub.

Appendix: source

Thrown at src/Data/GitHub/GitHubUpdater.cs:436

                Title = ResourceHelper.GetString("GitHubUpdater_Updating_Title"),
                Content = new ProgressRing() { IsIndeterminate = true },
            };
            _ = updatingDialog.ShowAsync();

            // Give the popup time to show.
            await Task.Delay(500);

            try
            {
                var processStartInfo = new ProcessStartInfo()
                {
                    FileName = tempDownloadFile,
                    UseShellExecute = true,
                };
                var installerProcess = Process.Start(processStartInfo);
                if (installerProcess is null)
                {
                    throw new Exception("Could not launch installer");
                }

                // Close DLSS Swapper so the installer can install
                Application.Current.Exit();
            }
            catch (Exception err)
            {
                Logger.Error(err);

                updatingDialog.Hide();

                var errorDialog = new EasyContentDialog(xamlRoot)
                {
                    Title = ResourceHelper.GetString("General_Error"),
                    Content = ResourceHelper.GetString("GitHubUpdater_CouldNotRunInstaller"),
                    PrimaryButtonText = ResourceHelper.GetString("GitHubUpdater_ViewUpdate"),
                    CloseButtonText = ResourceHelper.GetString("General_Cancel"),
                    DefaultButton = ContentDialogButton.Primary,

View on GitHub (pinned to ab9b1e2d4b)