Tauri 提供界面 + 使用 Rust 實現連接遠程 Linux 服務器、發送文件、執行命令

Tauri 提供界面 + 使用 rust 實現連接遠程 linux 服務器、發送文件、執行命令一、Tauri 概述

tauri 是一個用于構建跨平臺桌面應用程序的工具和框架。它的目標是通過將 web 技術與本地功能結合,使開發者能夠以簡單、高效的方式創建現代的桌面應用。

以下是 Tauri 的一些主要特點和概述:

跨平臺支持:Tauri 允許你構建跨平臺的桌面應用程序,它支持 windows、macos 和 Linux 等常見的操作系統。你可以使用一套代碼庫在多個平臺上構建應用程序。基于 Web 技術:Tauri 使用 Web 技術作為應用程序的前端開發語言。你可以使用 htmlcssJavaScript(或其他 Web 前端框架)來構建應用程序的用戶界面。原生功能訪問:Tauri 提供了訪問原生功能的接口,讓你可以從前端代碼中直接調用本地操作系統的功能,如文件系統、網絡、系統通知等。這樣,你可以創建出與本地應用程序類似的功能和體驗。嵌入式 Web 渲染引擎:Tauri 使用嵌入式的 Web 渲染引擎(如 webview 或 WebKitGTK)來渲染應用程序的界面。這使得應用程序可以直接在桌面環境中運行,而無需依賴外部的瀏覽器。豐富的生態系統:Tauri 生態系統提供了許多有用的功能和庫,如打包工具、插件系統、前端構建工具等,以便于應用程序的開發和部署。靈活的擴展性:Tauri 允許你通過使用 Rust 和 JavaScript 進行擴展,從而實現更復雜的功能。你可以編寫原生 Rust 代碼來訪問底層的系統功能,并使用 JavaScript 與前端代碼進行交互。

總的來說,Tauri 提供了一個快速、簡單的方式來開發跨平臺的桌面應用程序。通過結合 Web 技術和原生功能,你可以創建出功能豐富、具有優秀用戶體驗的桌面應用。無論是構建獨立的應用程序,還是將現有的 Web 應用轉化為桌面應用,Tauri 都是一個強大的選擇。

二、界面預覽

Tauri 提供界面 + 使用 Rust 實現連接遠程 Linux 服務器、發送文件、執行命令image-20230709233228823

三、代碼參考1、main.rs代碼語言:javascript代碼運行次數:0運行復制

// Prevents additional console window on Windows in release, DO NOT REMOVE!!#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]#![allow(unused_assignments)] // 禁用未使用賦值的警告use std::io::{Read, Write};use std::path::Path;use ssh2::Session;// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command#[tauri::command]fn go(ip_with_port: &str, username: &str, password: &str, local_file_path: &str, target_file_path: &str, command: &str) {    publish(ip_with_port, username, password, local_file_path, target_file_path, command)}fn main() {    tauri::Builder::default()        .invoke_handler(tauri::generate_handler![go])        .run(tauri::generate_context!())        .expect("error while running tauri application");}const PROGRESS_UPDATE_INTERVAL: usize = 1024 * 1024; // 每傳輸 1MB 打印一次進度信息// 發布fn publish(ip_with_port: &str, username: &str, password: &str, local_file_path: &str, target_file_path: &str, command: &str) {    // 連接遠程服務器    let tcp = std::net::TcpStream::connect(ip_with_port).unwrap(); // 連接到遠程服務器    let mut sess = Session::new().unwrap(); // 創建一個新的會話    sess.set_tcp_stream(tcp); // 設置會話的 TCP 流    sess.handshake().unwrap(); // 進行握手    sess.userauth_password(username, password).unwrap(); // 使用用戶名和密碼進行身份驗證    // 傳輸文件    let file_size = get_file_size(local_file_path); // 獲取文件大小    let mut channel = sess.scp_send(Path::new(target_file_path), 0o644, file_size, None).unwrap(); // 創建一個新的 SCP 通道    let mut file = std::fs::File::open(local_file_path).unwrap(); // 打開本地文件    let mut buffer = Vec::new(); // 創建一個空的字節向量    file.read_to_end(&mut buffer).unwrap(); // 讀取文件內容    let mut total_bytes_sent = 0; // 已發送的總字節數    let mut total_mb = (file_size as f64) / (1024.0 * 1024.0); // 文件總大小(MB)    total_mb = (total_mb * 100.0).round() / 100.0; // 保留2位小數    let mut transferred_mb = 0.0; // 已傳輸的文件大小(MB)    // 記錄已發送文件的大小    let mut bytes_sent = 0; // 已發送的字節數    for (i, chunk) in buffer.chunks(PROGRESS_UPDATE_INTERVAL).enumerate() { // 循環發送文件內容        // 循環發送,發完為止!        while bytes_sent < chunk.len() {            let result = channel.write(chunk).unwrap(); // 發送文件內容            bytes_sent += result; // 更新已發送的字節數        }        total_bytes_sent += bytes_sent; // 更新已發送的總字節數        bytes_sent = 0; // 重置已發送的字節數        transferred_mb = (total_bytes_sent as f64) / (1024.0 * 1024.0); // 更新已傳輸的文件大小(MB)        transferred_mb = (transferred_mb * 100.0).round() / 100.0; // 保留2位小數        if (i + 1) * PROGRESS_UPDATE_INTERVAL <= buffer.len() { // 如果還有剩余的文件內容需要發送            let progress = (total_bytes_sent as f64) / (file_size as f64) * 100.0; // 計算傳輸進度            println!("進度: {:.2}% ({:.2} MB / {:.2} MB)", progress, transferred_mb, total_mb); // 打印傳輸進度信息        } else { // 文件傳輸完畢            println!("進度: 100% 文件傳輸完畢!");        }    }    channel.send_eof().unwrap(); // 發送 EOF 標志    // 執行遠程命令    let mut channel = sess.channel_session().unwrap(); // 創建一個新的會話通道    channel.exec(command).unwrap(); // 執行命令    let mut output = Vec::new(); // 創建一個空的字節向量    channel.read_to_end(&mut output).unwrap(); // 讀取命令輸出    println!("{}", String::from_utf8_lossy(&output)); // 打印命令輸出}// 獲取文件大小fn get_file_size(file_path: &str) -> u64 {    std::fs::metadata(file_path) // 獲取文件元數據        .map(|metadata| metadata.len()) // 獲取文件大小        .unwrap_or(0) // 如果獲取失敗,則返回 0}

2、App.vue代碼語言:javascript代碼運行次數:0運行復制

<script setup lang="ts">import Greet from "./components/Greet.vue";</script><template>  <div class="container">    <h1>Spring Boot 程序發布工具!</h1>    <div class="tips">程序發布 = 連接 Linux + 發送文件 + 執行命令</div>    <Greet />  </div></template><style scoped>.tips {  color: #666666;  margin-bottom: 10px;}</style>

3、Greet.vue代碼語言:javascript代碼運行次數:0運行復制

<template>  <form class="row" @submit.prevent="go">    <input v-model="ipWithPort" placeholder="IP地址:端口號"/>    <input v-model="username" placeholder="賬號"/>    <input v-model="password" placeholder="密碼" type="password"/>    <input v-model="filePath" placeholder="本地文件路徑"/>    <input v-model="targetPath" placeholder="目標文件路徑"/>    <input v-model="command" placeholder="命令"/>    <button type="submit">執行!</button>  </form>  <p>{{result}}</p></template><script setup lang="ts">import {ref} from "vue";import {invoke} from "@tauri-apps/api/tauri";// IP地址和端口號:ip:portconst ipWithPort = ref("222.222.222.222:22");// 賬號const username = ref("root");// 密碼const password = ref("root");// 本地文件路徑const filePath = ref("C:\Users\Administrator\Desktop\app.jar");// 目標文件路徑const targetPath = ref("/home/zibo/app.jar");// 命令const command = ref("pwd");// 執行結果const result = ref("未開始執行!");async function go() {  result.value = "執行中...";  await invoke("go", {ipWithPort: ipWithPort.value, username: username.value, password: password.value, localFilePath: filePath.value, targetFilePath: targetPath.value, command: command.value});  result.value = "執行完畢!";}</script><style>.row {  display: flex;  flex-direction: column;  margin: 0 10px;}.row input {  margin-bottom: 10px;}</style>

4、依賴代碼語言:javascript代碼運行次數:0運行復制

# ssh2ssh2 = "0.9.4"

? 版權聲明
THE END
喜歡就支持一下吧
點贊14 分享