{"record":{"id":"ea8624e881fe32b5","repo":"beeradmoore/dlss-swapper","slug":"could-not-launch-installer","errorCode":null,"errorMessage":"Could not launch installer","messagePattern":"Could not launch installer","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/Data/GitHub/GitHubUpdater.cs","lineNumber":436,"sourceCode":"                Title = ResourceHelper.GetString(\"GitHubUpdater_Updating_Title\"),\n                Content = new ProgressRing() { IsIndeterminate = true },\n            };\n            _ = updatingDialog.ShowAsync();\n\n            // Give the popup time to show.\n            await Task.Delay(500);\n\n            try\n            {\n                var processStartInfo = new ProcessStartInfo()\n                {\n                    FileName = tempDownloadFile,\n                    UseShellExecute = true,\n                };\n                var installerProcess = Process.Start(processStartInfo);\n                if (installerProcess is null)\n                {\n                    throw new Exception(\"Could not launch installer\");\n                }\n\n                // Close DLSS Swapper so the installer can install\n                Application.Current.Exit();\n            }\n            catch (Exception err)\n            {\n                Logger.Error(err);\n\n                updatingDialog.Hide();\n\n                var errorDialog = new EasyContentDialog(xamlRoot)\n                {\n                    Title = ResourceHelper.GetString(\"General_Error\"),\n                    Content = ResourceHelper.GetString(\"GitHubUpdater_CouldNotRunInstaller\"),\n                    PrimaryButtonText = ResourceHelper.GetString(\"GitHubUpdater_ViewUpdate\"),\n                    CloseButtonText = ResourceHelper.GetString(\"General_Cancel\"),\n                    DefaultButton = ContentDialogButton.Primary,","sourceCodeStart":418,"sourceCodeEnd":454,"githubUrl":"https://github.com/beeradmoore/dlss-swapper/blob/ab9b1e2d4bb04187c48fe58eeea06c2b0ea71fbb/src/Data/GitHub/GitHubUpdater.cs#L418-L454","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check antivirus quarantine logs and whitelist the downloaded installer; re-run the update.","Verify the temp download file exists and is a valid executable (check size/signature) before Process.Start.","Ensure no other process has locked the temp file; reboot and retry the update.","Manually download the installer from the GitHub releases page and run it yourself."],"exampleFix":"// before\nvar installerProcess = Process.Start(processStartInfo);\nif (installerProcess is null)\n    throw new Exception(\"Could not launch installer\");\n// after\nif (File.Exists(tempDownloadFile) == false)\n    throw new Exception($\"Installer not found at {tempDownloadFile}\");\nvar installerProcess = Process.Start(processStartInfo);\nif (installerProcess is null)\n    throw new Exception($\"Could not launch installer at {tempDownloadFile}. It may be blocked by antivirus.\");","handlingStrategy":"validation","validationCode":"// Verify the installer exists and is non-trivially sized before launching\nif (File.Exists(tempDownloadFile) == false || new FileInfo(tempDownloadFile).Length < 1024)\n{\n    // don't attempt Process.Start; treat as failed download\n}","typeGuard":"bool CanLaunchInstaller(string path) => File.Exists(path) && new FileInfo(path).Length > 0;","tryCatchPattern":"try\n{\n    await updater.DownloadAndInstallAsync();\n}\ncatch (Exception ex) when (ex.Message == \"Could not launch installer\")\n{\n    logger.LogWarning(ex, \"Installer launch blocked; suggest manual install\");\n    // show dialog linking to the GitHub releases page\n}","preventionTips":["Verify the downloaded installer exists and has a plausible size/signature before Process.Start","Check antivirus/SmartScreen exclusion status for the temp download directory","Download to a stable, app-owned temp path rather than one that may be cleaned mid-flow","Provide a manual-install fallback path (open the releases page) when launch fails"],"tags":["process","installer","windows","update"],"backgroundTag":"command-not-found","analyzedSha":"ab9b1e2d4bb04187c48fe58eeea06c2b0ea71fbb","analyzedAt":"2026-09-15T05:25:32.979Z","contentChangedAt":"2026-09-15T05:25:32.979Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}