Skip to content

Commit

Permalink
Add packetry-cli wrapper program.
Browse files Browse the repository at this point in the history
This is necessary on Windows, where we can't have the same binary serve
as both a GUI and a console program, due to the constraints of the PE
binary format.

Instead, we add a new 'packetry-cli' console binary which simply acts as
a wrapper around the main GUI binary.

The wrapper sets the PACKETRY_ATTACH_CONSOLE environment variable, which
tells the main process to attach to the wrapping parent's console. The
wrapper waits for the child to complete, and mirrors its exit code.
  • Loading branch information
martinling committed Jul 31, 2024
1 parent e27176c commit 7aa98fd
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 1 deletion.
4 changes: 3 additions & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,12 @@ jobs:
- name: Upload binary
uses: actions/upload-artifact@v4
with:
name: Binary for ${{ matrix.os }}
name: Binaries for ${{ matrix.os }}
path: |
target/release/packetry
target/release/packetry.exe
target/release/packetry-cli
target/release/packetry-cli.exe
if-no-files-found: error
if: matrix.rust == 'stable'

Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

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

12 changes: 12 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ documentation = "https://packetry.readthedocs.io"
edition = "2021"
rust-version = "1.74"
build = "src/build.rs"
default-run = "packetry"

include = [
"CHANGELOG.md",
Expand Down Expand Up @@ -62,6 +63,9 @@ rand_xorshift = "0.3.0"
procspawn = "1.0.0"
ctor = "0.2.8"

[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3.9", features = ["wincon"] }

# Note: All of the current features are for debugging purposes only!
#
# None of them should be enabled for normal builds of the application.
Expand Down Expand Up @@ -110,3 +114,11 @@ record-ui-test = ["serde", "serde_json"]
# that is used internally by the model, and the changes being made to it.
#
debug-region-map = []

[[bin]]
name = "packetry"
path = "src/main.rs"

[[bin]]
name = "packetry-cli"
path = "src/cli.rs"
40 changes: 40 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use std::process::{Command, ExitCode};

#[cfg(windows)]
const MAIN_BINARY: &str = "packetry.exe";
#[cfg(not(windows))]
const MAIN_BINARY: &str = "packetry";

fn main() -> ExitCode {
// Find the main Packetry executable.
let packetry_binary_path = std::env::current_exe()
.expect("Failed to find path to current executable")
.parent()
.expect("Failed to find parent directory of current executable")
.join(MAIN_BINARY);

// Prepare to call it, passing through all arguments we were passed.
let mut command = Command::new(packetry_binary_path);
command.args(std::env::args().skip(1));

// If on Windows, tell the child that it needs to attach to our console.
#[cfg(windows)]
command.env("PACKETRY_ATTACH_CONSOLE", "1");

// Spawn the main binary as a child process, and wait for its exit status.
let exit_status = command
.status()
.expect("Failed to start main packetry binary");

// Try to exit with the same code the child did.
match exit_status.code() {
Some(code) => ExitCode::from(code as u8),
None => {
#[cfg(unix)]
if let Some(signal) = exit_status.signal() {
panic!("Packetry was terminated by signal {signal}");
}
panic!("Packetry was terminated without an exit code");
}
}
}
7 changes: 7 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ fn have_argument(name: &str) -> bool {
}

fn main() {
// On Windows, this env var will be set by the packetry-cli wrapper.
#[cfg(windows)]
if std::env::var("PACKETRY_ATTACH_CONSOLE").is_ok() {
use winapi::um::wincon::{AttachConsole, ATTACH_PARENT_PROCESS};
unsafe {AttachConsole(ATTACH_PARENT_PROCESS)};
}

if have_argument("--version") {
println!("Packetry version {}\n\n{}",
version(),
Expand Down
9 changes: 9 additions & 0 deletions wix/main.wxs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@
Source='$(var.CargoTargetBinDir)\packetry.exe'
KeyPath='yes'/>
</Component>
<Component Id='binary1' Guid='*'>
<File
Id='exe1'
Name='packetry-cli.exe'
DiskId='1'
Source='$(var.CargoTargetBinDir)\packetry-cli.exe'
KeyPath='yes'/>
</Component>
<?include dll-components.wxi ?>
</Directory>

Expand Down Expand Up @@ -142,6 +150,7 @@
<?include license-references.wxi ?>

<ComponentRef Id='binary0'/>
<ComponentRef Id='binary1'/>
<?include dll-references.wxi ?>

<ComponentRef Id='gschemas.compiled'/>
Expand Down

0 comments on commit 7aa98fd

Please sign in to comment.