mirror of
https://github.com/rustdesk/rustdesk.git
synced 2025-01-19 08:23:01 +08:00
Merge pull request #1591 from Kingtous/master
feat: windows flutter portable build script
This commit is contained in:
commit
752a94a5b5
@ -119,7 +119,7 @@ jni = "0.19"
|
||||
flutter_rust_bridge = { git = "https://github.com/SoLongAndThanksForAllThePizza/flutter_rust_bridge" }
|
||||
|
||||
[workspace]
|
||||
members = ["libs/scrap", "libs/hbb_common", "libs/enigo", "libs/clipboard", "libs/virtual_display", "libs/simple_rc"]
|
||||
members = ["libs/scrap", "libs/hbb_common", "libs/enigo", "libs/clipboard", "libs/virtual_display", "libs/simple_rc", "libs/portable"]
|
||||
|
||||
[package.metadata.winres]
|
||||
LegalCopyright = "Copyright © 2022 Purslane, Inc."
|
||||
|
27
build.py
27
build.py
@ -73,6 +73,11 @@ def make_parser():
|
||||
action='store_true',
|
||||
help='Enable feature hwcodec'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--portable',
|
||||
action='store_true',
|
||||
help='Build windows portable'
|
||||
)
|
||||
return parser
|
||||
|
||||
|
||||
@ -187,6 +192,20 @@ def build_flutter_arch_manjaro():
|
||||
os.chdir('..')
|
||||
os.system('HBB=`pwd` FLUTTER=1 makepkg -f')
|
||||
|
||||
def build_flutter_windows_portable():
|
||||
os.system("cargo build --lib --features flutter --release")
|
||||
os.chdir('flutter')
|
||||
os.system("flutter build windows --release")
|
||||
os.chdir('..')
|
||||
os.chdir("libs/portable")
|
||||
os.system("pip3 install -r requirements.txt")
|
||||
os.system("python3 .\\generate.py -f ..\\..\\flutter\\build\\windows\\runner\Release\ -o . -e ..\\..\\flutter\\build\\windows\\runner\\Release\\rustdesk.exe")
|
||||
os.chdir("../..")
|
||||
if os.path.exists("./rustdesk_portable.exe"):
|
||||
os.replace("./target/release/rustdesk-portable-packer.exe", "./rustdesk_portable.exe")
|
||||
else:
|
||||
os.rename("./target/release/rustdesk-portable-packer.exe", "./rustdesk_portable.exe")
|
||||
print(f"output location: {os.path.abspath(os.curdir)}/rustdesk_portable.exe")
|
||||
|
||||
def main():
|
||||
parser = make_parser()
|
||||
@ -201,13 +220,19 @@ def main():
|
||||
'//#![windows_subsystem', '#![windows_subsystem'))
|
||||
if os.path.exists(exe_path):
|
||||
os.unlink(exe_path)
|
||||
os.system('python3 res/inline-sciter.py')
|
||||
if os.path.isfile('/usr/bin/pacman'):
|
||||
os.system('git checkout src/ui/common.tis')
|
||||
version = get_version()
|
||||
features = ",".join(get_features(args))
|
||||
flutter = args.flutter
|
||||
if not flutter:
|
||||
# not flutter, is sciter
|
||||
os.system('python3 res/inline-sciter.py')
|
||||
portable = args.portable
|
||||
if windows:
|
||||
if portable:
|
||||
build_flutter_windows_portable()
|
||||
return
|
||||
os.system('cargo build --release --features ' + features)
|
||||
# os.system('upx.exe target/release/rustdesk.exe')
|
||||
os.system('mv target/release/rustdesk.exe target/release/RustDesk.exe')
|
||||
|
3
libs/portable/.gitignore
vendored
Normal file
3
libs/portable/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/target
|
||||
*.exe
|
||||
*.bin
|
285
libs/portable/Cargo.lock
generated
Normal file
285
libs/portable/Cargo.lock
generated
Normal file
@ -0,0 +1,285 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "alloc-no-stdlib"
|
||||
version = "2.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3"
|
||||
|
||||
[[package]]
|
||||
name = "alloc-stdlib"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece"
|
||||
dependencies = [
|
||||
"alloc-no-stdlib",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "brotli"
|
||||
version = "3.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68"
|
||||
dependencies = [
|
||||
"alloc-no-stdlib",
|
||||
"alloc-stdlib",
|
||||
"brotli-decompressor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "brotli-decompressor"
|
||||
version = "2.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59ad2d4653bf5ca36ae797b1f4bb4dbddb60ce49ca4aed8a2ce4829f60425b80"
|
||||
dependencies = [
|
||||
"alloc-no-stdlib",
|
||||
"alloc-stdlib",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "4.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
|
||||
dependencies = [
|
||||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embed-resource"
|
||||
version = "1.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "936c1354206a875581696369aef920e12396e93bbd251c43a7a3f3fa85023a7d"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"rustc_version",
|
||||
"toml",
|
||||
"vswhom",
|
||||
"winreg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.133"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966"
|
||||
|
||||
[[package]]
|
||||
name = "md5"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"redox_syscall",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustdesk-portable-packer"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"brotli",
|
||||
"dirs",
|
||||
"embed-resource",
|
||||
"md5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.144"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c53f98874615aea268107765aa1ed8f6116782501d18e53d08b471733bea6c85"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8b463991b4eab2d801e724172285ec4195c650e8ec79b149e6c2a8e6dd3f783"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd"
|
||||
|
||||
[[package]]
|
||||
name = "vswhom"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"vswhom-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vswhom-sys"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22025f6d8eb903ebf920ea6933b70b1e495be37e2cb4099e62c80454aaf57c39"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
16
libs/portable/Cargo.toml
Normal file
16
libs/portable/Cargo.toml
Normal file
@ -0,0 +1,16 @@
|
||||
[package]
|
||||
name = "rustdesk-portable-packer"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
build = "build.rs"
|
||||
|
||||
[build-dependencies]
|
||||
embed-resource = "1.7"
|
||||
|
||||
[dependencies]
|
||||
brotli = "3.3.4"
|
||||
dirs = "4.0.0"
|
||||
md5 = "0.7.0"
|
5
libs/portable/build.rs
Normal file
5
libs/portable/build.rs
Normal file
@ -0,0 +1,5 @@
|
||||
extern crate embed_resource;
|
||||
|
||||
fn main() {
|
||||
embed_resource::compile("icon.rc");
|
||||
}
|
88
libs/portable/generate.py
Normal file
88
libs/portable/generate.py
Normal file
@ -0,0 +1,88 @@
|
||||
from ast import parse
|
||||
import os
|
||||
import optparse
|
||||
from hashlib import md5
|
||||
import brotli
|
||||
|
||||
# file compress level(0-11)
|
||||
compress_level = 11
|
||||
# 4GB maximum
|
||||
length_count = 4
|
||||
# encoding
|
||||
encoding = 'utf-8'
|
||||
|
||||
# output: {path: (compressed_data, file_md5)}
|
||||
|
||||
|
||||
def generate_md5_table(folder: str) -> dict:
|
||||
res: dict = dict()
|
||||
curdir = os.curdir
|
||||
os.chdir(folder)
|
||||
for root, _, files in os.walk('.'):
|
||||
# remove ./
|
||||
for f in files:
|
||||
md5_generator = md5()
|
||||
full_path = os.path.join(root, f)
|
||||
print(f"processing {full_path}...")
|
||||
f = open(full_path, "rb")
|
||||
content = f.read()
|
||||
content_compressed = brotli.compress(
|
||||
content, quality=compress_level)
|
||||
md5_generator.update(content)
|
||||
md5_code = md5_generator.hexdigest().encode(encoding=encoding)
|
||||
res[full_path] = (content_compressed, md5_code)
|
||||
os.chdir(curdir)
|
||||
return res
|
||||
|
||||
|
||||
def write_metadata(md5_table: dict, output_folder: str, exe: str):
|
||||
output_path = os.path.join(output_folder, "data.bin")
|
||||
with open(output_path, "wb") as f:
|
||||
f.write("rustdesk".encode(encoding=encoding))
|
||||
for path in md5_table.keys():
|
||||
(compressed_data, md5_code) = md5_table[path]
|
||||
data_length = len(compressed_data)
|
||||
path = path.encode(encoding=encoding)
|
||||
# path length & path
|
||||
f.write((len(path)).to_bytes(length=length_count, byteorder='big'))
|
||||
f.write(path)
|
||||
# data length & compressed data
|
||||
f.write((data_length).to_bytes(
|
||||
length=length_count, byteorder='big'))
|
||||
f.write(compressed_data)
|
||||
# md5 code
|
||||
f.write(md5_code)
|
||||
# end
|
||||
f.write("rustdesk".encode(encoding=encoding))
|
||||
# executable
|
||||
f.write(exe.encode(encoding='utf-8'))
|
||||
print(f"metadata had written to {output_path}")
|
||||
|
||||
|
||||
def build_portable(output_folder: str):
|
||||
os.chdir(output_folder)
|
||||
os.system("cargo build --release")
|
||||
|
||||
# Linux: python3 generate.py -f ../rustdesk-portable-packer/test -o . -e ./test/main.py
|
||||
# Windows: python3 .\generate.py -f ..\rustdesk\flutter\build\windows\runner\Debug\ -o . -e ..\rustdesk\flutter\build\windows\runner\Debug\rustdesk.exe
|
||||
if __name__ == '__main__':
|
||||
parser = optparse.OptionParser()
|
||||
parser.add_option("-f", "--folder", dest="folder",
|
||||
help="folder to compress")
|
||||
parser.add_option("-o", "--output", dest="output_folder",
|
||||
help="the root of portable packer project")
|
||||
parser.add_option("-e", "--executable", dest="executable",
|
||||
help="specify startup file")
|
||||
(options, args) = parser.parse_args()
|
||||
folder = options.folder
|
||||
output_folder = os.path.abspath(options.output_folder)
|
||||
|
||||
exe: str = os.path.abspath(options.executable)
|
||||
if not exe.startswith(os.path.abspath(folder)):
|
||||
print("the executable must locate in source folder")
|
||||
exit(-1)
|
||||
exe = '.' + exe[len(os.path.abspath(folder)):]
|
||||
print("executable path: " + exe)
|
||||
md5_table = generate_md5_table(folder)
|
||||
write_metadata(md5_table, output_folder, exe)
|
||||
build_portable(output_folder)
|
1
libs/portable/icon.rc
Normal file
1
libs/portable/icon.rc
Normal file
@ -0,0 +1 @@
|
||||
rustdesk_icon ICON "../../res/icon.ico"
|
1
libs/portable/requirements.txt
Normal file
1
libs/portable/requirements.txt
Normal file
@ -0,0 +1 @@
|
||||
brotli
|
134
libs/portable/src/bin_reader.rs
Normal file
134
libs/portable/src/bin_reader.rs
Normal file
@ -0,0 +1,134 @@
|
||||
use std::{
|
||||
fs::{self},
|
||||
io::{Cursor, Read},
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
const BIN_DATA: &[u8] = include_bytes!("../data.bin");
|
||||
// 4bytes
|
||||
const LENGTH: usize = 4;
|
||||
const IDENTIFIER_LENGTH: usize = 8;
|
||||
const MD5_LENGTH: usize = 32;
|
||||
const BUF_SIZE: usize = 4096;
|
||||
|
||||
pub(crate) struct BinaryData {
|
||||
pub md5_code: &'static [u8],
|
||||
// compressed gzip data
|
||||
pub raw: &'static [u8],
|
||||
pub path: String,
|
||||
}
|
||||
|
||||
pub(crate) struct BinaryReader {
|
||||
pub files: Vec<BinaryData>,
|
||||
pub exe: String,
|
||||
}
|
||||
|
||||
impl Default for BinaryReader {
|
||||
fn default() -> Self {
|
||||
let (files, exe) = BinaryReader::read();
|
||||
Self { files, exe }
|
||||
}
|
||||
}
|
||||
|
||||
impl BinaryData {
|
||||
fn decompress(&self) -> Vec<u8> {
|
||||
let cursor = Cursor::new(self.raw);
|
||||
let mut decoder = brotli::Decompressor::new(cursor, BUF_SIZE);
|
||||
let mut buf = Vec::new();
|
||||
decoder.read_to_end(&mut buf).unwrap();
|
||||
buf
|
||||
}
|
||||
|
||||
pub fn write_to_file(&self, prefix: &PathBuf) {
|
||||
let p = prefix.join(&self.path);
|
||||
if let Some(parent) = p.parent() {
|
||||
if !parent.exists() {
|
||||
let _ = fs::create_dir_all(parent);
|
||||
}
|
||||
}
|
||||
if p.exists() {
|
||||
// check md5
|
||||
let f = fs::read(p.clone()).unwrap();
|
||||
let digest = format!("{:x}", md5::compute(&f));
|
||||
let md5_record = String::from_utf8_lossy(self.md5_code);
|
||||
if digest == md5_record {
|
||||
// same, skip this file
|
||||
println!("skip {}", &self.path);
|
||||
return;
|
||||
} else {
|
||||
println!("writing {}", p.display());
|
||||
println!("{} -> {}", md5_record, digest)
|
||||
}
|
||||
}
|
||||
let _ = fs::write(p, self.decompress());
|
||||
}
|
||||
}
|
||||
|
||||
impl BinaryReader {
|
||||
fn read() -> (Vec<BinaryData>, String) {
|
||||
let mut base: usize = 0;
|
||||
let mut parsed = vec![];
|
||||
assert!(BIN_DATA.len() > IDENTIFIER_LENGTH, "bin data invalid!");
|
||||
let mut iden = String::from_utf8_lossy(&BIN_DATA[base..base + IDENTIFIER_LENGTH]);
|
||||
if iden != "rustdesk" {
|
||||
panic!("bin file is not vaild!");
|
||||
}
|
||||
base += IDENTIFIER_LENGTH;
|
||||
loop {
|
||||
iden = String::from_utf8_lossy(&BIN_DATA[base..base + IDENTIFIER_LENGTH]);
|
||||
if iden == "rustdesk" {
|
||||
base += IDENTIFIER_LENGTH;
|
||||
break;
|
||||
}
|
||||
// start reading
|
||||
let mut offset = 0;
|
||||
let path_length = u32::from_be_bytes([
|
||||
BIN_DATA[base + offset],
|
||||
BIN_DATA[base + offset + 1],
|
||||
BIN_DATA[base + offset + 2],
|
||||
BIN_DATA[base + offset + 3],
|
||||
]) as usize;
|
||||
offset += LENGTH;
|
||||
let path =
|
||||
String::from_utf8_lossy(&BIN_DATA[base + offset..base + offset + path_length])
|
||||
.to_string();
|
||||
offset += path_length;
|
||||
// file sz
|
||||
let file_length = u32::from_be_bytes([
|
||||
BIN_DATA[base + offset],
|
||||
BIN_DATA[base + offset + 1],
|
||||
BIN_DATA[base + offset + 2],
|
||||
BIN_DATA[base + offset + 3],
|
||||
]) as usize;
|
||||
offset += LENGTH;
|
||||
let raw = &BIN_DATA[base + offset..base + offset + file_length];
|
||||
offset += file_length;
|
||||
// md5
|
||||
let md5 = &BIN_DATA[base + offset..base + offset + MD5_LENGTH];
|
||||
offset += MD5_LENGTH;
|
||||
parsed.push(BinaryData {
|
||||
md5_code: md5,
|
||||
raw: raw,
|
||||
path: path,
|
||||
});
|
||||
base += offset;
|
||||
}
|
||||
// executable
|
||||
let executable = String::from_utf8_lossy(&BIN_DATA[base..]).to_string();
|
||||
(parsed, executable)
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
pub fn configure_permission(&self, prefix: &PathBuf) {
|
||||
use std::os::unix::prelude::PermissionsExt;
|
||||
|
||||
let exe_path = prefix.join(&self.exe);
|
||||
if exe_path.exists() {
|
||||
let f = File::open(exe_path).unwrap();
|
||||
let meta = f.metadata().unwrap();
|
||||
let mut permissions = meta.permissions();
|
||||
permissions.set_mode(0o755);
|
||||
f.set_permissions(permissions).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
51
libs/portable/src/main.rs
Normal file
51
libs/portable/src/main.rs
Normal file
@ -0,0 +1,51 @@
|
||||
#![windows_subsystem = "windows"]
|
||||
|
||||
use std::{
|
||||
path::PathBuf,
|
||||
process::{Command, Stdio},
|
||||
};
|
||||
|
||||
use bin_reader::BinaryReader;
|
||||
|
||||
pub mod bin_reader;
|
||||
|
||||
const APP_PREFIX: &str = "rustdesk";
|
||||
const APPNAME_RUNTIME_ENV_KEY: &str = "RUSTDESK_APPNAME";
|
||||
|
||||
fn setup(reader: BinaryReader) -> Option<PathBuf> {
|
||||
// home dir
|
||||
if let Some(dir) = dirs::data_local_dir() {
|
||||
let dir = dir.join(APP_PREFIX);
|
||||
for file in reader.files.iter() {
|
||||
file.write_to_file(&dir);
|
||||
}
|
||||
#[cfg(unix)]
|
||||
reader.configure_permission(&dir);
|
||||
Some(dir.join(&reader.exe))
|
||||
} else {
|
||||
eprintln!("not found data local dir");
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn execute(path: PathBuf) {
|
||||
println!("executing {}", path.display());
|
||||
// setup env
|
||||
let exe = std::env::current_exe().unwrap();
|
||||
let exe_name = exe.file_name().unwrap();
|
||||
// run executable
|
||||
Command::new(path)
|
||||
.env(APPNAME_RUNTIME_ENV_KEY, exe_name)
|
||||
.stdin(Stdio::inherit())
|
||||
.stdout(Stdio::inherit())
|
||||
.stderr(Stdio::inherit())
|
||||
.output()
|
||||
.expect(&format!("failed to execute {:?}", exe_name));
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let reader = BinaryReader::default();
|
||||
if let Some(exe) = setup(reader) {
|
||||
execute(exe);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user