lostindark/DriverStoreExplorer · error · InvalidOperationException

Failed to restart the application. Please restart manually.

Error message

Failed to restart the application. Please restart manually.

What it means

Thrown by AboutBox after ApplyUpdateAsync has already replaced the executable: the updater renames the running exe and copies the new one in place, then calls Process.Start(exePath) to relaunch. System.Diagnostics.Process.Start(string) returns null when no process resource is created (e.g. UseShellExecute association failure, an invalid/locked executable, or the shell open call returns without spawning). The exception is only a post-update courtesy message — the files are already swapped and the app exits immediately after.

Source

Thrown at Rapr/AboutBox.cs:204

                this.labelLink.Links.Clear();
                string versionStr = this.latestVersionInfo.Version.ToString();
                this.labelLink.Text = string.Format(Language.Update_Downloading, versionStr, 0);

                var progress = new Progress<float>(p =>
                {
                    this.labelLink.Text = string.Format(Language.Update_Downloading, versionStr, (int)(p * 100));
                });

                string exePath = Application.ExecutablePath;

                await this.updateManager.ApplyUpdateAsync(this.latestVersionInfo, progress);

                if (!this.updateManager.HandlesRestart)
                {
                    var newProcess = Process.Start(exePath);
                    if (newProcess == null)
                    {
                        throw new InvalidOperationException("Failed to restart the application. Please restart manually.");
                    }
                }

                Application.Exit();
            }
            catch (Exception ex)
            {
                MessageBox.Show(
                    string.Format(Language.Update_Failed, ex.Message),
                    Language.Product_Name,
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);

                // Reset the link
                this.latestVersionInfo = null;
                _ = this.UpdateLatestVersionInfo();
            }
        }

View on GitHub (pinned to 958fcd481b)

Solutions

  1. Relaunch the application manually from its folder — the update has already been applied, so the running files are current.
  2. Pass a ProcessStartInfo with UseShellExecute=true and WorkingDirectory set to the app directory so the shell association launches the new binary.
  3. Confirm the new exe is not blocked: right-click > Properties > Unblock, or check AV quarantine logs.
  4. Log exePath and File.Exists(exePath) right before Process.Start to distinguish 'file missing' from 'launch refused'.
  5. If the launch must be guaranteed, fall back to a scheduled task / cmd.exe start delayed by 1s so the old process can exit and release locks first.

Example fix

// before
var newProcess = Process.Start(exePath);
if (newProcess == null)
{
    throw new InvalidOperationException("Failed to restart the application. Please restart manually.");
}

// after
var psi = new ProcessStartInfo
{
    FileName = exePath,
    UseShellExecute = true,
    WorkingDirectory = Path.GetDirectoryName(exePath),
};
var newProcess = Process.Start(psi);
if (newProcess == null || newProcess.HasExited)
{
    MessageBox.Show(
        "Update applied successfully. Please relaunch the application manually.",
        Language.Product_Name,
        MessageBoxButtons.OK,
        MessageBoxIcon.Information);
}
else
{
    Application.Exit();
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Guard before attempting the relaunch
if (!File.Exists(exePath))
{
    MessageBox.Show(
        "The updated executable was not found at " + exePath + ".",
        Language.Product_Name,
        MessageBoxButtons.OK,
        MessageBoxIcon.Warning);
    return;
}

var psi = new ProcessStartInfo
{
    FileName = exePath,
    UseShellExecute = true,
    WorkingDirectory = Path.GetDirectoryName(exePath) ?? string.Empty,
};
var proc = Process.Start(psi);
if (proc == null || proc.HasExited) { /* manual restart path */ }

Try / catch

// AboutBox.PerformUpdateAsync already wraps the whole flow in try/catch.
// Narrow the catch so a restart failure is reported distinctly from a download/apply failure.
try
{
    await this.updateManager.ApplyUpdateAsync(this.latestVersionInfo, progress);
}
catch (Exception applyEx)
{
    MessageBox.Show(string.Format(Language.Update_Failed, applyEx.Message),
        Language.Product_Name, MessageBoxButtons.OK, MessageBoxIcon.Error);
    return;
}

try
{
    var proc = Process.Start(new ProcessStartInfo(exePath) { UseShellExecute = true });
    if (proc == null || proc.HasExited)
    {
        MessageBox.Show("Update applied. Please restart manually.",
            Language.Product_Name, MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    else
    {
        Application.Exit();
    }
}
catch (Exception restartEx)
{
    // Files are updated; restart is the only thing that failed.
    MessageBox.Show("Update applied but auto-restart failed: " + restartEx.Message,
        Language.Product_Name, MessageBoxButtons.OK, MessageBoxIcon.Warning);
}

Prevention

When it happens

Trigger: Line 201 calls Process.Start(exePath) where exePath is the just-overwritten executable. If the runtime returns null (no Process instance because the launch did not produce a resource handle), the guard at line 202 fires. HandslesRestart is false on UpdateManager (line 21), so this branch always executes.

Common situations: Antivirus or AppLocker blocks execution of the freshly-written exe; the new file is still being flushed and is momentarily locked; UseShellExecute=false (the .NET Framework default on some overloads) cannot resolve the bare path; a corporate policy or missing execute permission prevents spawning; exePath resolved to a path the user cannot execute.

Related errors


AI-assisted analysis of lostindark/DriverStoreExplorer@958fcd481b (2026-08-13). Data as JSON: /api/errors/1c50885e94aa8a0a. Report an issue: GitHub.