-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement automatic Rokit installation when launching from Windows Ex…
…plorer
- Loading branch information
1 parent
8bae269
commit c1155e7
Showing
5 changed files
with
157 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,9 @@ | ||
mod current; | ||
mod env; | ||
mod process; | ||
mod runner; | ||
|
||
pub use self::current::{current_dir, current_exe, current_exe_contents, current_exe_name}; | ||
pub use self::env::{add_to_path, exists_in_path}; | ||
pub use self::process::{Launcher as ProcessLauncher, Parent as ProcessParent}; | ||
pub use self::runner::run_interruptible; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
#![allow(clippy::unused_async)] | ||
|
||
use std::io::{stderr, stdout, IsTerminal}; | ||
|
||
#[cfg(unix)] | ||
mod unix; | ||
|
||
#[cfg(windows)] | ||
mod windows; | ||
|
||
#[cfg(unix)] | ||
use self::unix as platform; | ||
|
||
#[cfg(windows)] | ||
use self::windows as platform; | ||
|
||
/** | ||
Enum representing possible sources that may have launched Rokit. | ||
Note that this in non-exhaustive, and may be extended in the future. | ||
*/ | ||
#[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
#[non_exhaustive] | ||
pub enum Launcher { | ||
WindowsExplorer, | ||
MacOsFinder, | ||
} | ||
|
||
/** | ||
Enum representing the detected kind of parent process of Rokit. | ||
Note that this in non-exhaustive, and may be extended in the future. | ||
*/ | ||
#[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
#[non_exhaustive] | ||
pub enum Parent { | ||
Launcher(Launcher), | ||
Terminal, | ||
} | ||
|
||
impl Parent { | ||
/** | ||
Returns `true` if the parent is a launcher. | ||
*/ | ||
#[must_use] | ||
pub const fn is_launcher(self) -> bool { | ||
matches!(self, Self::Launcher(_)) | ||
} | ||
|
||
/** | ||
Returns `true` if the parent is a terminal. | ||
*/ | ||
#[must_use] | ||
pub const fn is_terminal(self) -> bool { | ||
matches!(self, Self::Terminal) | ||
} | ||
|
||
/** | ||
Tries to detect the parent process of Rokit. | ||
Returns `None` if the parent process could not be detected. | ||
*/ | ||
pub async fn get() -> Option<Self> { | ||
platform::try_detect_launcher() | ||
.await | ||
.map(Self::Launcher) | ||
.or_else(|| { | ||
if stdout().is_terminal() || stderr().is_terminal() { | ||
Some(Self::Terminal) | ||
} else { | ||
None | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
pub async fn try_detect_launcher() -> Option<super::Launcher> { | ||
// FUTURE: Try to detect if this process was launched from Finder / Linux equivalent | ||
None | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
use winapi::um::processthreadsapi::GetCurrentProcessId; | ||
use winapi::um::wincon::GetConsoleProcessList; | ||
|
||
use super::Launcher; | ||
|
||
pub async fn try_detect_launcher() -> Option<super::Launcher> { | ||
tracing::debug!("trying to detect launcher using Windows API"); | ||
|
||
/* | ||
Allocate a buffer for process IDs - we need space for at | ||
least one ID, which will hopefully be our own process ID | ||
*/ | ||
let mut process_list = [0u32; 1]; | ||
let process_id = unsafe { GetCurrentProcessId() }; | ||
let process_count = unsafe { GetConsoleProcessList(process_list.as_mut_ptr(), 1) }; | ||
|
||
tracing::debug!( | ||
id = %process_id, | ||
count = %process_count, | ||
"got process id and count" | ||
); | ||
|
||
/* | ||
If there's only one process (our process), the console will be destroyed on exit, | ||
this very likely means it was launched from Explorer or a similar environment. | ||
A similar environment could be the download folder in a web browser, | ||
launching the program directly using the "Run" dialog, ..., but for | ||
simplicity we'll just assume it was launched from Explorer. | ||
*/ | ||
if process_count == 1 && process_list[0] == process_id { | ||
Some(Launcher::WindowsExplorer) | ||
} else { | ||
None | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters