@uaquax

Как запустить команду без терминала в Rust?

**Я довольно много изучал** эту проблему, но не нашел решения. Мне нужно запустить двоичные файлы (в Windows .exe) в приложении Tauri GUI. Проблема в том, что когда я делаю это **в режиме dev**, я **не вижу окон** терминалов. Полагаю, это потому, что я запускаю его через терминал(**cargo tauri dev**). Однако в режиме release это так.

Мне нужно решение, чтобы это окно было скрыто или не отображалось. Может быть, мне следует запустить его в отдельном потоке, может быть, следует скрыть его с помощью какой-нибудь команды по идентификатору процесса или даже создать свой собственный минимальный эмулятор терминала. Я действительно понятия не имею, как это исправить. Пожалуйста, помогите мне.

Если вам нужна дополнительная информация, просто скажите мне, и я дам все, что вам нужно.

P.s. Я не могу интегрировать этот исполняемый файл в свой код, потому что он проприетарный и, скорее всего, написан на C++.

Вот что **я попробовал**:

/* 
Ничего не сработало

#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
#![cfg_attr(windows_subsystem = "windows")]
#![windows_subsystem = "windows"]

*/




fn main() {
    <...>
}


Вот мой код:

// src-tauri/main.rs

#![windows_subsystem = "windows"]

mod my_class;
// <...>

#[tauri::command]
fn my_actual_handler(some_var: &str) {
    let my_class = MyClass::new(some_var);
    my_class.execute();
}

fn main() {
    <...>
    tauri::Builder::default().handlers(my_actual_handler).run();
}


// src-tauri/my_class.rs

pub struct MyClass {
    some_var: String,
    child: child: RwLock<Option<Child>>,
}

impl MyClass {
   <...>
   
    pub fn execute(&self) {
        let child = Command::new(env::current_dir().unwrap().join("my_app.exe"))
            .arg("some args")
            .arg(
                env::current_dir()
                    .unwrap()
                    .join("data")
                    .join(format!("{}.json", "more data")),
            )
            // .stdout(Stdio::piped()) - уже пробовал, не помогло null() тоже
            // .stderr(Stdio::piped()) - уже пробовал, не помогло null() тоже
            .spawn()
            .expect("ERROR: Failed to start the child process");
        
        /* I Мне нужно сохранять child для того чтобы в будущем его останавливать, если вы знаете способ получше, то скажите пожалуйста*/
        let mut child_lock = self.child.write().expect("RwLock write lock failed");
        *child_lock = Some(child);
    }
}
  • Вопрос задан
  • 97 просмотров
Пригласить эксперта
Ответы на вопрос 1
Torin_Asakura
@Torin_Asakura
Lead Architect
Уже пробовал танцевать с `std::process::Command`? Например с `creation_flags` из `std::os::windows::process::CommandExt`. Для того чтобы запустить процесс без окна терминала, можно использовать флаг `CREATE_NO_WINDOW`.

Немного пошаманил с твоим кодом

use std::env;
use std::os::windows::process::CommandExt;
use std::process::Command;
use std::sync::RwLock;
use tauri;

const CREATE_NO_WINDOW: u32 = 0x08000000;

pub struct MyClass {
    some_var: String,
    child: RwLock<Option<std::process::Child>>,
}

impl MyClass {
    pub fn new(some_var: &str) -> MyClass {
        MyClass {
            some_var: some_var.to_string(),
            child: RwLock::new(None),
        }
    }

    pub fn execute(&self) {
        let child = Command::new(env::current_dir().unwrap().join("my_app.exe"))
            .arg("some args")
            .arg(
                env::current_dir()
                    .unwrap()
                    .join("data")
                    .join(format!("{}.json", "more data")),
            )
            .creation_flags(CREATE_NO_WINDOW)
            .spawn()
            .expect("ERROR: Failed to start the child process");

        let mut child_lock = self.child.write().unwrap();
        *child_lock = Some(child);
    }
}

#[tauri::command]
fn my_actual_handler(some_var: &str) {
    let my_class = MyClass::new(some_var);
    my_class.execute();
}

fn main() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![my_actual_handler])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы