1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*! Restart the current process after an update.
After [`update()`](crate::update::ReleaseUpdate::update) reports
[`VersionStatus::Updated`](crate::VersionStatus::Updated) it has already replaced the running
executable on disk (via [`self_replace`](https://crates.io/crates/self-replace)), but the *live*
process keeps running the old code until it exits. To pick up the new binary immediately, restart
into it.
Two entry points:
- [`restart`] re-runs the new binary with the **same arguments** the current process was launched
with (`std::env::args_os().skip(1)`).
- [`restart_with`] re-runs it with **arguments you supply**, for the common case of dropping a flag
so the restarted process does not immediately update again (e.g. a `--upgrade` subcommand that
should not recurse).
Both inherit the current environment. On success neither returns (the return type is
[`Infallible`](std::convert::Infallible)); they yield `Err` only when the restart itself could not
be started.
## Platform behavior
- **Unix:** the process image is replaced in place with
[`exec`](std::os::unix::process::CommandExt::exec), so the PID is preserved and nothing returns on
success.
- **Windows:** there is no `exec`. The new binary is **spawned** as a separate process (inheriting
stdio) and the current process then exits with code `0`. The PID therefore changes, and a console
application's replacement runs in the same console.
Because the running executable was already replaced on disk, the restart launches the *updated*
binary, not the old one.
```rust,no_run
fn run() -> Result<(), Box<dyn std::error::Error>> {
let status = self_update::backends::github::Update::configure()
.repo_owner("jaemk")
.repo_name("self_update")
.bin_name("myapp")
.current_version(self_update::cargo_crate_version!())
.build()?
.update()?;
if status.is_updated() {
// Relaunch without the `--upgrade` flag so the new process runs normally
// instead of trying to update itself again.
self_update::restart::restart_with(["run"])?;
}
Ok(())
}
```
*/
use crate*;
use Infallible;
use OsStr;
use Command;
/// Build the [`Command`] that restarts the current process: the current executable
/// ([`current_exe`](std::env::current_exe)) with `args` and the inherited environment.
///
/// Factored out so the argument/target wiring is testable without actually replacing the process.
/// Restart the current process, re-running the (already updated) executable with the **same
/// arguments** it was launched with.
///
/// Equivalent to [`restart_with`] passing `std::env::args_os().skip(1)`. See the
/// [module docs](crate::restart) for platform behavior. On success this does not return; it yields
/// `Err(Error::Io(..))` only if the restart could not be started.
/// Restart the current process, re-running the (already updated) executable with the arguments in
/// `args` (replacing, not appending to, the original arguments) and the inherited environment.
///
/// Use this to relaunch with a different argument list than the current process was started with,
/// e.g. dropping an `--upgrade` flag so the restarted process runs normally instead of updating
/// again. See the [module docs](crate::restart) for platform behavior. On success this does not
/// return; it yields `Err(Error::Io(..))` only if the restart could not be started.
///
/// ```rust,no_run
/// # fn run() -> Result<(), Box<dyn std::error::Error>> {
/// // Relaunch the updated binary with a fresh argument list.
/// self_update::restart::restart_with(["run", "--quiet"])?;
/// # Ok(())
/// # }
/// ```
/// See the unix version above; on windows there is no `exec`, so this spawns the updated binary as
/// a new process (inheriting stdio) and then exits the current process with code `0`.