私はおそらく環境変数を取得し、それを反復処理し、最初に一致したパスを返したい:あなたは実行可能ファイル名に.exe
を追加する必要があるだろうと
use std::env;
use std::path::{Path, PathBuf};
fn find_it<P>(exe_name: P) -> Option<PathBuf>
where P: AsRef<Path>,
{
env::var_os("PATH").and_then(|paths| {
env::split_paths(&paths).filter_map(|dir| {
let full_path = dir.join(&exe_name);
if full_path.is_file() {
Some(full_path)
} else {
None
}
}).next()
})
}
fn main() {
println!("{:?}", find_it("cat"));
println!("{:?}", find_it("dog"));
}
は、これはおそらく、Windows上で醜いです。また、実行可能な項目だけを返すように拡張する必要があります。これは、プラットフォーム固有のコードです。
を確認すると、渡される絶対パスもサポートされているようです。関数がそれをサポートするかどうかは、あなた次第です。それは現在
は、現在唯一のUnixライクなオペレーティングシステム上で動作すると言うものの、quale:
crates.ioの迅速な検索が有用である可能性がある1つのクレートを返されました。
他にもあることがわかりました。
ここでそれが唯一のWindows上で、欠けている場合は最後に.exe
を追加し、いくつかの醜いコードです。
#[cfg(not(target_os = "windows"))]
fn enhance_exe_name(exe_name: &Path) -> Cow<Path> {
exe_name.into()
}
#[cfg(target_os = "windows")]
fn enhance_exe_name(exe_name: &Path) -> Cow<Path> {
use std::ffi::OsStr;
use std::os::windows::ffi::OsStrExt;
let raw_input: Vec<_> = exe_name.as_os_str().encode_wide().collect();
let raw_extension: Vec<_> = OsStr::new(".exe").encode_wide().collect();
if raw_input.ends_with(&raw_extension) {
exe_name.into()
} else {
let mut with_exe = exe_name.as_os_str().to_owned();
with_exe.push(".exe");
PathBuf::from(with_exe).into()
}
}
// At the top of the `find_it` function:
// let exe_name = enhance_exe_name(exe_name.as_ref());
「.exe」を使用してブラインドではなく、本当に正しいです。 'PATHEXT'環境変数を使用することになっています。これは'実行可能 'とみなされるファイル拡張子の ';'で区切られたリストです。残念ながら、 'CreateProcess'(Rustの' Command'型がAFAIKをサポートしている)はネイティブの実行可能な型しかサポートしていないので、注意する必要があります。シェルスクリプト)。だから、あなたが 'ShellExecute'を使って独自のコードを書こうとしているのでなければ(Rustは私には分かりません)、おそらく' .COM; .EXE'に制限するべきです。 –
@DKクロスプラットフォームの作業は難しいです!それが価値あるものであれば、ここのコードはPythonがやっていることを模倣していますが、WindowsのPythonサポートがどれほど素晴らしいかわかりません。多分、私たちはこれをクレート(クワールのような?)に提出するべきです。 – Shepmaster
ええ、私は実際にWin32のコードを書くことなく、Rustでこれを行う方法が実際にはないことを(文字がなくなると)書きました。なぜなら、あなたが正しく 'commandname.py'か何かを見つけたとしても実際には呼び出すことはできません。スクリプトを実行するとカーネル機能ではなくシェル機能であることは、あなたが得たものだと思います... –