Add AllowSetForegroundWindow to every Process.Start call

This commit is contained in:
Caelan Sayler
2024-01-26 13:08:35 +00:00
parent 04cf01cc87
commit 10a7f7264d
2 changed files with 20 additions and 20 deletions

View File

@@ -18,6 +18,7 @@ use windows::{
}, },
}; };
use winsafe::{self as w, co}; use winsafe::{self as w, co};
use windows::Win32::UI::WindowsAndMessaging::AllowSetForegroundWindow;
pub fn run_hook(app: &shared::bundle::Manifest, root_path: &PathBuf, hook_name: &str, timeout_secs: u64) { pub fn run_hook(app: &shared::bundle::Manifest, root_path: &PathBuf, hook_name: &str, timeout_secs: u64) {
let sw = simple_stopwatch::Stopwatch::start_new(); let sw = simple_stopwatch::Stopwatch::start_new();
@@ -235,6 +236,8 @@ where
.creation_flags(CREATE_NO_WINDOW) .creation_flags(CREATE_NO_WINDOW)
.spawn()?; .spawn()?;
let _ = unsafe { AllowSetForegroundWindow(cmd.id()) };
fn check_process_status_and_output(status: std::process::ExitStatus, mut cmd: std::process::Child) -> Result<String> { fn check_process_status_and_output(status: std::process::ExitStatus, mut cmd: std::process::Child) -> Result<String> {
let mut stdout = cmd.stdout.take().unwrap(); let mut stdout = cmd.stdout.take().unwrap();
let mut stderr = cmd.stderr.take().unwrap(); let mut stderr = cmd.stderr.take().unwrap();
@@ -273,25 +276,8 @@ where
S: AsRef<OsStr>, S: AsRef<OsStr>,
P: AsRef<Path>, P: AsRef<Path>,
{ {
Process::new(exe).args(args).current_dir(work_dir).spawn()?; let cmd = Process::new(exe).args(args).current_dir(work_dir).spawn()?;
Ok(()) let _ = unsafe { AllowSetForegroundWindow(cmd.id()) };
}
pub fn run_process_no_console<S, P>(exe: S, args: Vec<&str>, work_dir: P) -> Result<()>
where
S: AsRef<OsStr>,
P: AsRef<Path>,
{
Process::new(exe).args(args).current_dir(work_dir).creation_flags(CREATE_NO_WINDOW).spawn()?;
Ok(())
}
pub fn run_process_no_console_raw_args<S, P>(exe: S, args: &str, work_dir: P) -> Result<()>
where
S: AsRef<OsStr>,
P: AsRef<Path>,
{
Process::new(exe).raw_arg(args).current_dir(work_dir).creation_flags(CREATE_NO_WINDOW).spawn()?;
Ok(()) Ok(())
} }
@@ -300,7 +286,8 @@ where
S: AsRef<OsStr>, S: AsRef<OsStr>,
P: AsRef<Path>, P: AsRef<Path>,
{ {
Process::new(exe).raw_arg(args).current_dir(work_dir).spawn()?; let cmd = Process::new(exe).raw_arg(args).current_dir(work_dir).spawn()?;
let _ = unsafe { AllowSetForegroundWindow(cmd.id()) };
Ok(()) Ok(())
} }

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
@@ -16,6 +17,10 @@ namespace Velopack
/// </summary> /// </summary>
public static class UpdateExe public static class UpdateExe
{ {
[DllImport("user32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool AllowSetForegroundWindow(int dwProcessId);
/// <summary> /// <summary>
/// Runs Update.exe in the current working directory to apply updates, optionally restarting the application. /// Runs Update.exe in the current working directory to apply updates, optionally restarting the application.
/// </summary> /// </summary>
@@ -62,6 +67,14 @@ namespace Velopack
logger.Debug($"Restarting app to apply updates. Running: {psi.FileName} {debugArgs}"); logger.Debug($"Restarting app to apply updates. Running: {psi.FileName} {debugArgs}");
var p = Process.Start(psi); var p = Process.Start(psi);
try {
// this is an attempt to work around a bug where the restarted app fails to come to foreground.
AllowSetForegroundWindow(p.Id);
} catch (Exception ex) {
logger.LogWarning(ex, "Failed to allow Update.exe to set foreground window.");
}
Thread.Sleep(300); Thread.Sleep(300);
if (p == null) { if (p == null) {
throw new Exception("Failed to launch Update.exe process."); throw new Exception("Failed to launch Update.exe process.");