Skip to content

Commit

Permalink
Merge branch 'md/windows-command'
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Feb 5, 2023
2 parents eea4f27 + 1f4a9f9 commit 0d09f28
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 67 deletions.
6 changes: 1 addition & 5 deletions .github/workflows/cross-platform-testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
RUST_BACKTRACE: 1
strategy:
matrix:
build: [linux, linux-arm, macos, win-msvc, win-gnu, win32-msvc]
build: [linux, linux-arm, macos, win-msvc, win-gnu]
include:
- build: linux
os: ubuntu-18.04
Expand All @@ -42,10 +42,6 @@ jobs:
os: windows-2019
rust: stable
target: x86_64-pc-windows-gnu
- build: win32-msvc
os: windows-2019
rust: stable
target: i686-pc-windows-msvc

steps:
- name: Checkout repository
Expand Down
3 changes: 0 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,5 @@ test = false
doc = false
name = "open"

[target.'cfg(windows)'.dependencies]
windows-sys = { version = "0.42", features = ["Win32_UI_Shell", "Win32_Foundation", "Win32_UI_WindowsAndMessaging"] }

[target.'cfg(all(unix, not(macos)))'.dependencies]
pathdiff = "0.2.0"
73 changes: 14 additions & 59 deletions src/windows.rs
Original file line number Diff line number Diff line change
@@ -1,66 +1,21 @@
use std::{
ffi::{OsStr, OsString},
io,
os::windows::ffi::OsStrExt,
ptr,
};
use std::{ffi::OsStr, io};

use std::os::raw::c_int;
use windows_sys::Win32::UI::Shell::ShellExecuteW;
use windows_sys::Win32::UI::WindowsAndMessaging::SW_SHOW;

use crate::IntoResult;

fn convert_path(path: &OsStr) -> io::Result<Vec<u16>> {
let mut quoted_path = OsString::with_capacity(path.len());

// Surround path with double quotes "" to handle spaces in path.
quoted_path.push("\"");
quoted_path.push(&path);
quoted_path.push("\"");

let mut wide_chars: Vec<_> = quoted_path.encode_wide().collect();
if wide_chars.iter().any(|&u| u == 0) {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"path contains NUL byte(s)",
));
}
wide_chars.push(0);
Ok(wide_chars)
}
use crate::{CommandExt, IntoResult};

pub fn that<T: AsRef<OsStr>>(path: T) -> io::Result<()> {
let path = convert_path(path.as_ref())?;
let operation: Vec<u16> = OsStr::new("open\0").encode_wide().collect();
let result = unsafe {
ShellExecuteW(
0,
operation.as_ptr(),
path.as_ptr(),
ptr::null(),
ptr::null(),
SW_SHOW,
)
};
(result as c_int).into_result()
std::process::Command::new("cmd")
.arg("/c")
.arg("start")
.arg(path.as_ref())
.status_without_output()
.into_result()
}

pub fn with<T: AsRef<OsStr>>(path: T, app: impl Into<String>) -> io::Result<()> {
let path = convert_path(path.as_ref())?;
let operation: Vec<u16> = OsStr::new("open\0").encode_wide().collect();
let app_name: Vec<u16> = OsStr::new(&format!("{}\0", app.into()))
.encode_wide()
.collect();
let result = unsafe {
ShellExecuteW(
0,
operation.as_ptr(),
app_name.as_ptr(),
path.as_ptr(),
ptr::null(),
SW_SHOW,
)
};
(result as c_int).into_result()
std::process::Command::new("cmd")
.arg("/c")
.arg(app.into())
.arg(path.as_ref())
.status_without_output()
.into_result()
}

0 comments on commit 0d09f28

Please sign in to comment.