Skip to content

Commit

Permalink
Support receiving current exe path as argument (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidkna authored Jul 21, 2024
1 parent 35955bd commit e397c01
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 9 deletions.
9 changes: 9 additions & 0 deletions demo.bat
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ if not exist target\debug\examples\deletes-itself.exe (
echo deletes-itself.exe was successfully deleted
)

echo.
echo Run deletes-itself-at.exe
target\debug\examples\deletes-itself-at.exe
if not exist target\debug\examples\deletes-itself-at.exe (
if not exist target\debug\examples\deletes-itself-renamed.exe (
echo deletes-itself-at.exe and deletes-itself-renamed.exe were successfully deleted
)
)

echo.
echo Run hello.exe
target\debug\examples\hello.exe
Expand Down
8 changes: 8 additions & 0 deletions demo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ if [ ! -f target/debug/examples/deletes-itself ]; then
echo " deletes-itself.exe was successfully deleted"
fi

echo
echo "Run deletes-itself-at.exe"
target/debug/examples/deletes-itself-at

if [ ! -f target/debug/examples/deletes-itself-renamed ] && [ ! -f target/debug/examples/deletes-itself-at ]; then
echo " deletes-itself-at.exe and deletes-itself-renamed.exe were successfully deleted"
fi

echo
echo "Run hello.exe"
target/debug/examples/hello
Expand Down
15 changes: 15 additions & 0 deletions examples/deletes-itself-at.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
fn main() {
println!("When I finish, I am deleted");
let exe = std::env::current_exe().unwrap().canonicalize().unwrap();
let exe_renamed = exe.with_file_name(format!(
"deletes-itself-renamed{}",
std::env::consts::EXE_SUFFIX
));

std::fs::rename(exe, &exe_renamed).unwrap();
self_replace::self_delete_at(exe_renamed).unwrap();

if std::env::var("FORCE_EXIT").ok().as_deref() == Some("1") {
std::process::exit(0);
}
}
16 changes: 12 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,20 @@ mod windows;
/// # Ok(()) }
/// ```
pub fn self_delete() -> Result<(), io::Error> {
self_delete_at(std::env::current_exe()?)
}

/// Like [`self_delete`] but accepts a path which is assumed to be the current executable path.
///
/// This can be useful if the executable was moved to a different location while it was running.
pub fn self_delete_at<P: AsRef<Path>>(exe: P) -> Result<(), io::Error> {
#[cfg(unix)]
{
crate::unix::self_delete()
crate::unix::self_delete(exe.as_ref())
}
#[cfg(windows)]
{
crate::windows::self_delete(None)
crate::windows::self_delete(exe.as_ref(), None)
}
}

Expand All @@ -150,14 +157,15 @@ pub fn self_delete() -> Result<(), io::Error> {
/// of the deletion operation. This is necessary to demolish folder more complex folder
/// structures on Windows.
pub fn self_delete_outside_path<P: AsRef<Path>>(p: P) -> Result<(), io::Error> {
let exe = std::env::current_exe()?;
#[cfg(unix)]
{
let _ = p;
crate::unix::self_delete()
crate::unix::self_delete(&exe)
}
#[cfg(windows)]
{
crate::windows::self_delete(Some(p.as_ref()))
crate::windows::self_delete(&exe, Some(p.as_ref()))
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use std::io;
use std::path::Path;

/// On Unix a running executable can be safely deleted.
pub fn self_delete() -> Result<(), io::Error> {
let exe = env::current_exe()?.canonicalize()?;
pub fn self_delete(exe: &Path) -> Result<(), io::Error> {
let exe = exe.canonicalize()?;
fs::remove_file(exe)?;
Ok(())
}
Expand Down
5 changes: 2 additions & 3 deletions src/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,8 @@ fn get_directory_of(p: &Path) -> Result<&Path, io::Error> {
/// actually shuts down.
/// 4. In `self_delete_on_init` spawn a dummy process so that windows deletes the
/// copy too.
pub fn self_delete(protected_path: Option<&Path>) -> Result<(), io::Error> {
let exe = env::current_exe()?.canonicalize()?;
schedule_self_deletion_on_shutdown(&exe, protected_path)?;
pub fn self_delete(exe: &Path, protected_path: Option<&Path>) -> Result<(), io::Error> {
schedule_self_deletion_on_shutdown(exe, protected_path)?;
Ok(())
}

Expand Down

0 comments on commit e397c01

Please sign in to comment.