Skip to content

Commit

Permalink
Move install code to dedicated admin exe to reduce usage in bat files
Browse files Browse the repository at this point in the history
  • Loading branch information
MolotovCherry committed Nov 11, 2024
1 parent 6f1a4a7 commit a92e353
Show file tree
Hide file tree
Showing 11 changed files with 175 additions and 105 deletions.
10 changes: 9 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
[workspace]
resolver = "2"
members = ["crates/loader", "crates/shared", "crates/yabg3nml"]
members = [
"crates/autostart-installer",
"crates/loader",
"crates/shared",
"crates/yabg3nml",
]

[workspace.dependencies]
tracing = "0.1.40"
Expand Down
13 changes: 1 addition & 12 deletions assets/install.bat
Original file line number Diff line number Diff line change
@@ -1,14 +1,3 @@
@echo off

set SCRIPT_DIR=%~dp0

REM Check for administrative privileges
net session >nul 2>&1
if %errorlevel% neq 0 (
REM Elevate script to run as administrator
echo Requesting administrative privileges...
powershell -Command "Start-Process '%0' -Verb runAs -WorkingDirectory '%SCRIPT_DIR%'"
exit /b
)

START /B %~dp0\bg3_autostart.exe --install
%~dp0\autostart-installer.exe --install
13 changes: 1 addition & 12 deletions assets/uninstall.bat
Original file line number Diff line number Diff line change
@@ -1,14 +1,3 @@
@echo off

set SCRIPT_DIR=%~dp0

REM Check for administrative privileges
net session >nul 2>&1
if %errorlevel% neq 0 (
REM Elevate script to run as administrator
echo Requesting administrative privileges...
powershell -Command "Start-Process '%0' -Verb runAs -WorkingDirectory '%SCRIPT_DIR%'"
exit /b
)

START /B %~dp0\bg3_autostart.exe --uninstall
%~dp0\autostart-installer.exe --uninstall
11 changes: 11 additions & 0 deletions crates/autostart-installer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "autostart-installer"
version = "0.1.0"
edition = "2021"

[dependencies]
shared.workspace = true
winreg = "0.52.0"

[build-dependencies]
winres.workspace = true
20 changes: 20 additions & 0 deletions crates/autostart-installer/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use std::error::Error;
use std::path::Path;
use std::{env, fs};

fn main() -> Result<(), Box<dyn Error>> {
if !cfg!(target_os = "windows") {
panic!("Only windows OS is supported");
}

let mut res = winres::WindowsResource::new();

let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let dir = Path::new(&manifest_dir);
let manifest = fs::read_to_string(dir.join("manifest.xml"))?;
res.set_manifest(&manifest);

res.compile()?;

Ok(())
}
36 changes: 36 additions & 0 deletions crates/autostart-installer/manifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 10 and Windows 11 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application>
</compatibility>
<asmv3:application>
<asmv3:windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">system</dpiAwareness>
</asmv3:windowsSettings>
</asmv3:application>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
<trustInfo>
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="requireAdministrator"
uiAccess="false"
/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
88 changes: 88 additions & 0 deletions crates/autostart-installer/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

use std::{env, io, process::ExitCode};

use shared::popup::{display_popup, fatal_popup, MessageBoxIcon};
use winreg::{enums::HKEY_LOCAL_MACHINE, RegKey};

const HELP: &str = r"autostart-installer
Installs the bg3_autostart. Automatically patches bg3 when the game is launched, without needing to manually
run any tool. Installs registry entries at:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\bg3.exe
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\bg3_dx11.exe
Flags:
--install install the autostarter
--uninstall uninstall the autostarter
--help this message
";

fn main() -> ExitCode {
let Some(flag) = env::args().nth(1) else {
fatal_popup("No flags", "No install/uninstall/help flags were specified");
};

let is_install = flag == "--install";
let is_uninstall = flag == "--uninstall";

if is_install {
if let Err(e) = install() {
fatal_popup("install failed", format!("{e}"));
};

display_popup("Success", "bg3_autostart was successfully installed.\n\nEvery time you launch bg3, your game will be auto patched. If you want to stop this from happening, please uninstall the tool using the provided uninstall.bat. Also, do not move bg3_autostart.exe after you install. If you wish to move it, please first uninstall, move the tool, then reinstall.\n\nPlease also note that the registry entries point at the current bg3_autostart.exe location. If this file is in your windows user folder and another windows user tries to launch the game, they may not have access to the exe in your windows user folder (since it's another windows user's files). If multiple windows users play this game, you should instead place this exe at a location accessible by all windows users to avoid this problem. Also, if you delete the tools, make sure to uninstall first!", MessageBoxIcon::Info);
ExitCode::SUCCESS
} else if is_uninstall {
if let Err(e) = uninstall() {
fatal_popup("uninstall failed", format!("{e}"));
};

display_popup(
"Success",
"bg3_autostart was successfully uninstalled.",
MessageBoxIcon::Info,
);
ExitCode::SUCCESS
} else {
display_popup("Usage", HELP, MessageBoxIcon::Info);
ExitCode::SUCCESS
}
}

const HKLM: RegKey = RegKey::predef(HKEY_LOCAL_MACHINE);
#[rustfmt::skip]
const R_BG3: &str = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\bg3.exe";
#[rustfmt::skip]
const R_BG3_DX11: &str = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\bg3_dx11.exe";

fn install() -> io::Result<()> {
let (bg3_key, _) = HKLM.create_subkey(R_BG3)?;
let (bg3_dx11_key, _) = HKLM.create_subkey(R_BG3_DX11)?;

let cur_exe = {
let mut c = env::current_exe()?;
c.pop();

c.join("bg3_autostart.exe")
};

if !cur_exe.exists() {
fatal_popup(
"Missing",
"bg3_autostart.exe needs to be in the same folder as autostart_installer.exe",
);
}

bg3_key.set_value("debugger", &&*cur_exe.to_string_lossy())?;
bg3_dx11_key.set_value("debugger", &&*cur_exe.to_string_lossy())?;

Ok(())
}

fn uninstall() -> io::Result<()> {
HKLM.delete_subkey_all(R_BG3)?;
HKLM.delete_subkey_all(R_BG3_DX11)?;

Ok(())
}
1 change: 0 additions & 1 deletion crates/yabg3nml/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ widestring = "1.1.0"
rand = "0.8.5"
# todo: remove sptr when strict provenance apis are stable
sptr = "0.3.2"
winreg = "0.52.0"

[dependencies.argh]
git = "https://github.com/google/argh"
Expand Down
80 changes: 2 additions & 78 deletions crates/yabg3nml/src/bin/bg3_autostart.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

use std::{
env, io,
env,
os::windows::process::CommandExt as _,
path::Path,
process::{self, Command, ExitCode},
Expand All @@ -17,61 +17,10 @@ use windows::Win32::System::{
Diagnostics::Debug::DebugActiveProcessStop,
Threading::{DEBUG_ONLY_THIS_PROCESS, DEBUG_PROCESS},
};
use winreg::{enums::HKEY_LOCAL_MACHINE, RegKey};
use yabg3nml::get_game_binary_paths;

const HELP: &str = r"bg3_autostart

Automatically patches bg3 when the game is launched, without needing to manually
run any tool. Installs registry entries at:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\bg3.exe
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\bg3_dx11.exe
Flags:
--install install the autostarter
--uninstall uninstall the autostarter
--help this message
";
use yabg3nml::get_game_binary_paths;

fn main() -> ExitCode {
let Some(flag) = env::args().nth(1) else {
fatal_popup(
"No flags",
"No install/uninstall/help flags were specified. Also, keep in mind that this autostart program is not a launcher. Please check instructions for how to use it.",
);
};

let is_install = flag == "--install";
let is_uninstall = flag == "--uninstall";
let is_help = flag == "--help";

if is_install {
if let Err(e) = install() {
fatal_popup("install failed", format!("{e}"));
};

display_popup("Success", "bg3_autostart was successfully installed.\n\nEvery time you launch bg3, your game will be auto patched. If you want to stop this from happening, please uninstall the tool using the provided uninstall.bat. Also, do not move bg3_autostart.exe after you install. If you wish to move it, please first uninstall, move the tool, then reinstall.\n\nPlease also note that the registry entries point at the current bg3_autostart.exe location. If this file is in your windows user folder and another windows user tries to launch the game, they may not have access to the exe in your windows user folder (since it's another windows user's files). If multiple windows users play this game, you should instead place this exe at a location accessible by all windows users to avoid this problem. Also, if you delete the tools, make sure to uninstall first!", MessageBoxIcon::Info);
ExitCode::SUCCESS
} else if is_uninstall {
if let Err(e) = uninstall() {
fatal_popup("uninstall failed", format!("{e}"));
};

display_popup(
"Success",
"bg3_autostart was successfully uninstalled.",
MessageBoxIcon::Info,
);
ExitCode::SUCCESS
} else if is_help {
display_popup("Usage", HELP, MessageBoxIcon::Info);
ExitCode::SUCCESS
} else {
autostart()
}
}

fn autostart() -> ExitCode {
// [this_exe_path, bg3_exe_path, ..args]
let args = env::args().skip(2);

Expand Down Expand Up @@ -181,28 +130,3 @@ fn autostart() -> ExitCode {
.map(|s| ExitCode::from(s.code().unwrap_or(1).clamp(u8::MIN as _, u8::MAX as _) as u8))
.unwrap_or(ExitCode::FAILURE)
}

const HKLM: RegKey = RegKey::predef(HKEY_LOCAL_MACHINE);
#[rustfmt::skip]
const R_BG3: &str = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\bg3.exe";
#[rustfmt::skip]
const R_BG3_DX11: &str = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\bg3_dx11.exe";

fn install() -> io::Result<()> {
let (bg3_key, _) = HKLM.create_subkey(R_BG3)?;
let (bg3_dx11_key, _) = HKLM.create_subkey(R_BG3_DX11)?;

let cur_exe = env::current_exe()?;

bg3_key.set_value("debugger", &&*cur_exe.to_string_lossy())?;
bg3_dx11_key.set_value("debugger", &&*cur_exe.to_string_lossy())?;

Ok(())
}

fn uninstall() -> io::Result<()> {
HKLM.delete_subkey_all(R_BG3)?;
HKLM.delete_subkey_all(R_BG3_DX11)?;

Ok(())
}
1 change: 1 addition & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ _build profile="debug" flags="" flags2="":
echo "Loader hash is ${env:LOADER_HASH}"
echo "Building yabg3nml..."
cargo build -p yabg3nml {{flags2}}
cargo build -p autostart-installer {{flags2}}

build: _build

Expand Down

0 comments on commit a92e353

Please sign in to comment.