mirror of
https://github.com/rustdesk/rustdesk.git
synced 2024-11-27 14:59:02 +08:00
simple_rc: win init simple resource pack
Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
parent
e1bb25c70e
commit
2081113bed
12
Cargo.lock
generated
12
Cargo.lock
generated
@ -4093,6 +4093,7 @@ dependencies = [
|
||||
"serde_derive",
|
||||
"serde_json 1.0.79",
|
||||
"sha2",
|
||||
"simple_rc",
|
||||
"sys-locale",
|
||||
"sysinfo",
|
||||
"tray-item",
|
||||
@ -4446,6 +4447,17 @@ version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f054c6c1a6e95179d6f23ed974060dcefb2d9388bb7256900badad682c499de4"
|
||||
|
||||
[[package]]
|
||||
name = "simple_rc"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"confy",
|
||||
"hbb_common",
|
||||
"serde 1.0.136",
|
||||
"serde_derive",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.2.3"
|
||||
|
@ -19,6 +19,7 @@ path = "src/naming.rs"
|
||||
inline = []
|
||||
hbbs = []
|
||||
cli = []
|
||||
with_rc = ["simple_rc"]
|
||||
use_samplerate = ["samplerate"]
|
||||
use_rubato = ["rubato"]
|
||||
use_dasp = ["dasp"]
|
||||
@ -103,7 +104,7 @@ jni = "0.19.0"
|
||||
flutter_rust_bridge = "1.30.0"
|
||||
|
||||
[workspace]
|
||||
members = ["libs/scrap", "libs/hbb_common", "libs/enigo", "libs/clipboard", "libs/virtual_display"]
|
||||
members = ["libs/scrap", "libs/hbb_common", "libs/enigo", "libs/clipboard", "libs/virtual_display", "libs/simple_rc"]
|
||||
|
||||
[package.metadata.winres]
|
||||
LegalCopyright = "Copyright © 2022 Purslane, Inc."
|
||||
@ -117,6 +118,7 @@ winapi = { version = "0.3", features = [ "winnt" ] }
|
||||
[build-dependencies]
|
||||
cc = "1.0"
|
||||
hbb_common = { path = "libs/hbb_common" }
|
||||
simple_rc = { path = "libs/simple_rc", optional = true }
|
||||
flutter_rust_bridge_codegen = "1.30.0"
|
||||
|
||||
[dev-dependencies]
|
||||
|
16
build.rs
16
build.rs
@ -27,6 +27,20 @@ fn build_manifest() {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(windows, feature = "with_rc"))]
|
||||
fn build_rc_source() {
|
||||
use simple_rc::{generate_with_conf, Config, ConfigItem};
|
||||
generate_with_conf(&Config {
|
||||
outfile: "src/rc.rs".to_owned(),
|
||||
confs: vec![ConfigItem {
|
||||
inc: "resources".to_owned(),
|
||||
exc: vec![],
|
||||
suppressed_front: "resources".to_owned(),
|
||||
}],
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn install_oboe() {
|
||||
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
|
||||
if target_os != "android" {
|
||||
@ -87,6 +101,8 @@ fn main() {
|
||||
gen_flutter_rust_bridge();
|
||||
return;
|
||||
}
|
||||
#[cfg(all(windows, feature = "with_rc"))]
|
||||
build_rc_source();
|
||||
#[cfg(all(windows, feature = "inline"))]
|
||||
build_manifest();
|
||||
#[cfg(windows)]
|
||||
|
13
libs/simple_rc/Cargo.toml
Normal file
13
libs/simple_rc/Cargo.toml
Normal file
@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "simple_rc"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
serde_derive = "1.0"
|
||||
serde = "1.0"
|
||||
walkdir = "2"
|
||||
confy = { git = "https://github.com/open-trade/confy" }
|
||||
hbb_common = { path = "../hbb_common" }
|
23
libs/simple_rc/examples/generate.rs
Normal file
23
libs/simple_rc/examples/generate.rs
Normal file
@ -0,0 +1,23 @@
|
||||
extern crate simple_rc;
|
||||
|
||||
use simple_rc::*;
|
||||
|
||||
fn main() {
|
||||
{
|
||||
const CONF_FILE: &str = "simple_rc.toml";
|
||||
generate(CONF_FILE).unwrap();
|
||||
}
|
||||
|
||||
{
|
||||
generate_with_conf(&Config {
|
||||
outfile: "src/rc.rs".to_owned(),
|
||||
confs: vec![ConfigItem {
|
||||
inc: "D:/projects/windows/RustDeskTempTopMostWindow/x64/Release/xxx".to_owned(),
|
||||
// exc: vec!["*.dll".to_owned(), "*.exe".to_owned()],
|
||||
exc: vec![],
|
||||
suppressed_front: "D:/projects/windows".to_owned(),
|
||||
}],
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
}
|
12
libs/simple_rc/simple_rc.toml
Normal file
12
libs/simple_rc/simple_rc.toml
Normal file
@ -0,0 +1,12 @@
|
||||
# The output source file
|
||||
outfile = "src/rc.rs"
|
||||
|
||||
# The resource config list.
|
||||
[[confs]]
|
||||
# The file or director to integrate.
|
||||
inc = "D:/projects/windows/RustDeskTempTopMostWindow/x64/Release/xxx"
|
||||
# The exclusions.
|
||||
exc = ["*.dll", "*.exe"]
|
||||
# The front path that will ignore for extracting.
|
||||
# The following config will make base output path to be "RustDeskTempTopMostWindow/x64/Release/xxx".
|
||||
suppressed_front = "D:/projects/windows"
|
208
libs/simple_rc/src/lib.rs
Normal file
208
libs/simple_rc/src/lib.rs
Normal file
@ -0,0 +1,208 @@
|
||||
use hbb_common::{bail, ResultType};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::{collections::HashMap, fs::File, io::prelude::*, path::Path};
|
||||
use walkdir::WalkDir;
|
||||
|
||||
//mod rc;
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Serialize, Deserialize, Clone)]
|
||||
pub struct ConfigItem {
|
||||
// include directory or file
|
||||
pub inc: String,
|
||||
// exclude files
|
||||
pub exc: Vec<String>,
|
||||
// out_path = origin_path - suppressed_front
|
||||
pub suppressed_front: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Serialize, Deserialize, Clone)]
|
||||
pub struct Config {
|
||||
// output source file
|
||||
pub outfile: String,
|
||||
// config items
|
||||
pub confs: Vec<ConfigItem>,
|
||||
}
|
||||
|
||||
pub fn get_outin_files<'a>(item: &'a ConfigItem) -> ResultType<HashMap<String, String>> {
|
||||
let mut outin_filemap = HashMap::new();
|
||||
|
||||
for entry in WalkDir::new(&item.inc).follow_links(true) {
|
||||
let path = entry?.into_path();
|
||||
if path.is_file() {
|
||||
let mut exclude = false;
|
||||
for excfile in item.exc.iter() {
|
||||
if excfile.starts_with("*.") {
|
||||
if let Some(ext) = path.extension().and_then(|x| x.to_str()) {
|
||||
if excfile.ends_with(&format!(".{}", ext)) {
|
||||
exclude = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if path.ends_with(Path::new(excfile)) {
|
||||
exclude = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if exclude {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut suppressed_front = item.suppressed_front.clone();
|
||||
if !suppressed_front.is_empty() && suppressed_front.ends_with('/') {
|
||||
suppressed_front.push('/');
|
||||
}
|
||||
let outpath = path.strip_prefix(Path::new(&suppressed_front))?;
|
||||
let outfile = if outpath.is_absolute() {
|
||||
match outpath
|
||||
.file_name()
|
||||
.and_then(|f| f.to_str())
|
||||
.map(|f| f.to_string())
|
||||
{
|
||||
None => {
|
||||
bail!("Failed to get filename of {}", outpath.display());
|
||||
}
|
||||
Some(s) => s,
|
||||
}
|
||||
} else {
|
||||
match outpath.to_str() {
|
||||
None => {
|
||||
bail!("Failed to convert {} to string", outpath.display());
|
||||
}
|
||||
// Simple replace \ to / here.
|
||||
// A better way is to use lib [path-slash](https://github.com/rhysd/path-slash)
|
||||
Some(s) => s.to_string().replace("\\", "/"),
|
||||
}
|
||||
};
|
||||
let infile = match path.canonicalize()?.to_str() {
|
||||
None => {
|
||||
bail!("Failed to get file path of {}", path.display());
|
||||
}
|
||||
Some(s) => s.to_string(),
|
||||
};
|
||||
if let Some(_) = outin_filemap.insert(outfile.clone(), infile) {
|
||||
bail!("outfile {} is set before", outfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(outin_filemap)
|
||||
}
|
||||
|
||||
pub fn generate(conf_file: &str) -> ResultType<()> {
|
||||
let conf = confy::load_path(conf_file)?;
|
||||
generate_with_conf(&conf)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn generate_with_conf<'a>(conf: &'a Config) -> ResultType<()> {
|
||||
let mut outfile = File::create(&conf.outfile)?;
|
||||
|
||||
outfile.write(
|
||||
br##"use hbb_common::{bail, ResultType};
|
||||
use std::{
|
||||
fs::{self, File},
|
||||
io::prelude::*,
|
||||
path::Path,
|
||||
};
|
||||
|
||||
"##,
|
||||
)?;
|
||||
|
||||
outfile.write(b"#[allow(dead_code)]\n")?;
|
||||
outfile.write(b"pub fn extract_resources(root_path: &str) -> ResultType<()> {\n")?;
|
||||
outfile.write(b" let mut resources: Vec<(&str, &[u8])> = Vec::new();\n")?;
|
||||
|
||||
let mut outin_files = HashMap::new();
|
||||
for item in conf.confs.iter() {
|
||||
for (o, i) in get_outin_files(item)?.into_iter() {
|
||||
if let Some(_) = outin_files.insert(o.clone(), i) {
|
||||
bail!("outfile {} is set before", o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut count = 1;
|
||||
for (o, i) in outin_files.iter() {
|
||||
let mut infile = File::open(&i)?;
|
||||
let mut buffer = Vec::<u8>::new();
|
||||
infile.read_to_end(&mut buffer)?;
|
||||
|
||||
let var_outfile = format!("outfile_{}", count);
|
||||
let var_outdata = format!("outdata_{}", count);
|
||||
|
||||
write!(outfile, " let {} = \"{}\";\n", var_outfile, o)?;
|
||||
write!(outfile, " let {}: &[u8] = &[\n ", var_outdata)?;
|
||||
|
||||
let mut line_num = 20;
|
||||
for v in buffer {
|
||||
if line_num == 0 {
|
||||
write!(outfile, "\n ")?;
|
||||
line_num = 20;
|
||||
}
|
||||
write!(outfile, "{:#04x}, ", v)?;
|
||||
line_num -= 1;
|
||||
}
|
||||
write!(outfile, "\n ];\n")?;
|
||||
|
||||
write!(
|
||||
outfile,
|
||||
" resources.push(({}, &{}));\n",
|
||||
var_outfile, var_outdata
|
||||
)?;
|
||||
|
||||
count += 1;
|
||||
}
|
||||
|
||||
outfile.write(b" do_extract(root_path, resources)?;\n")?;
|
||||
outfile.write(b" Ok(())\n")?;
|
||||
outfile.write(b"}\n")?;
|
||||
|
||||
outfile.write(
|
||||
br##"
|
||||
#[allow(dead_code)]
|
||||
fn do_extract(root_path: &str, resources: Vec<(&str, &[u8])>) -> ResultType<()> {
|
||||
let mut root_path = root_path.replace("\\", "/");
|
||||
if !root_path.ends_with('/') {
|
||||
root_path.push('/');
|
||||
}
|
||||
let root_path = Path::new(&root_path);
|
||||
for (outfile, data) in resources {
|
||||
let outfile_path = root_path.join(outfile);
|
||||
match outfile_path.parent().and_then(|p| p.to_str()) {
|
||||
None => {
|
||||
bail!("Failed to get parent of {}", outfile_path.display());
|
||||
}
|
||||
Some(p) => {
|
||||
fs::create_dir_all(p)?;
|
||||
let mut of = File::create(outfile_path)?;
|
||||
of.write_all(data)?;
|
||||
of.flush()?;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
"##,
|
||||
)?;
|
||||
|
||||
outfile.flush()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn it_works() {
|
||||
let result = 2 + 2;
|
||||
assert_eq!(result, 4);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn test_extract() {
|
||||
// use super::*;
|
||||
// rc::extract_resources("D:").unwrap();
|
||||
// }
|
||||
}
|
@ -1,12 +1,14 @@
|
||||
#[cfg(windows)]
|
||||
use virtual_display::win10::{idd, DRIVER_INSTALL_PATH};
|
||||
|
||||
#[cfg(windows)]
|
||||
use std::{
|
||||
ffi::CStr,
|
||||
io::{self, Read},
|
||||
path::Path,
|
||||
};
|
||||
|
||||
#[cfg(windows)]
|
||||
fn prompt_input() -> u8 {
|
||||
println!("Press key execute:");
|
||||
println!(" 1. 'x' 1. exit");
|
||||
@ -24,6 +26,7 @@ fn prompt_input() -> u8 {
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
unsafe fn plug_in(index: idd::UINT, edid: idd::UINT) {
|
||||
println!("Plug in monitor begin");
|
||||
if idd::FALSE == idd::MonitorPlugIn(index, edid, 25) {
|
||||
@ -48,6 +51,7 @@ unsafe fn plug_in(index: idd::UINT, edid: idd::UINT) {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
unsafe fn plug_out(index: idd::UINT) {
|
||||
println!("Plug out monitor begin");
|
||||
if idd::FALSE == idd::MonitorPlugOut(index) {
|
||||
@ -58,88 +62,91 @@ unsafe fn plug_out(index: idd::UINT) {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let abs_path = Path::new(DRIVER_INSTALL_PATH).canonicalize().unwrap();
|
||||
#[cfg(windows)]
|
||||
{
|
||||
let abs_path = Path::new(DRIVER_INSTALL_PATH).canonicalize().unwrap();
|
||||
|
||||
unsafe {
|
||||
let invalid_device = 0 as idd::HSWDEVICE;
|
||||
let mut h_sw_device = invalid_device;
|
||||
unsafe {
|
||||
let invalid_device = 0 as idd::HSWDEVICE;
|
||||
let mut h_sw_device = invalid_device;
|
||||
|
||||
let full_inf_path: Vec<u16> = abs_path
|
||||
.to_string_lossy()
|
||||
.as_ref()
|
||||
.encode_utf16()
|
||||
.chain(Some(0).into_iter())
|
||||
.collect();
|
||||
let full_inf_path: Vec<u16> = abs_path
|
||||
.to_string_lossy()
|
||||
.as_ref()
|
||||
.encode_utf16()
|
||||
.chain(Some(0).into_iter())
|
||||
.collect();
|
||||
|
||||
loop {
|
||||
match prompt_input() as char {
|
||||
'x' => break,
|
||||
'i' => {
|
||||
println!("Install or update driver begin, {}", abs_path.display());
|
||||
let mut reboot_required = idd::FALSE;
|
||||
if idd::InstallUpdate(full_inf_path.as_ptr() as _, &mut reboot_required)
|
||||
== idd::FALSE
|
||||
{
|
||||
println!("{}", CStr::from_ptr(idd::GetLastMsg()).to_str().unwrap());
|
||||
} else {
|
||||
println!(
|
||||
"Install or update driver done, reboot is {} required",
|
||||
if reboot_required == idd::FALSE {
|
||||
"not"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
);
|
||||
loop {
|
||||
match prompt_input() as char {
|
||||
'x' => break,
|
||||
'i' => {
|
||||
println!("Install or update driver begin, {}", abs_path.display());
|
||||
let mut reboot_required = idd::FALSE;
|
||||
if idd::InstallUpdate(full_inf_path.as_ptr() as _, &mut reboot_required)
|
||||
== idd::FALSE
|
||||
{
|
||||
println!("{}", CStr::from_ptr(idd::GetLastMsg()).to_str().unwrap());
|
||||
} else {
|
||||
println!(
|
||||
"Install or update driver done, reboot is {} required",
|
||||
if reboot_required == idd::FALSE {
|
||||
"not"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
'u' => {
|
||||
println!("Uninstall driver begin {}", abs_path.display());
|
||||
let mut reboot_required = idd::FALSE;
|
||||
if idd::Uninstall(full_inf_path.as_ptr() as _, &mut reboot_required)
|
||||
== idd::FALSE
|
||||
{
|
||||
println!("{}", CStr::from_ptr(idd::GetLastMsg()).to_str().unwrap());
|
||||
} else {
|
||||
println!(
|
||||
"Uninstall driver done, reboot is {} required",
|
||||
if reboot_required == idd::FALSE {
|
||||
"not"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
);
|
||||
'u' => {
|
||||
println!("Uninstall driver begin {}", abs_path.display());
|
||||
let mut reboot_required = idd::FALSE;
|
||||
if idd::Uninstall(full_inf_path.as_ptr() as _, &mut reboot_required)
|
||||
== idd::FALSE
|
||||
{
|
||||
println!("{}", CStr::from_ptr(idd::GetLastMsg()).to_str().unwrap());
|
||||
} else {
|
||||
println!(
|
||||
"Uninstall driver done, reboot is {} required",
|
||||
if reboot_required == idd::FALSE {
|
||||
"not"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
'c' => {
|
||||
println!("Create device begin");
|
||||
if h_sw_device != invalid_device {
|
||||
println!("Device created before");
|
||||
continue;
|
||||
'c' => {
|
||||
println!("Create device begin");
|
||||
if h_sw_device != invalid_device {
|
||||
println!("Device created before");
|
||||
continue;
|
||||
}
|
||||
if idd::FALSE == idd::DeviceCreate(&mut h_sw_device) {
|
||||
println!("{}", CStr::from_ptr(idd::GetLastMsg()).to_str().unwrap());
|
||||
idd::DeviceClose(h_sw_device);
|
||||
h_sw_device = invalid_device;
|
||||
} else {
|
||||
println!("Create device done");
|
||||
}
|
||||
}
|
||||
if idd::FALSE == idd::DeviceCreate(&mut h_sw_device) {
|
||||
println!("{}", CStr::from_ptr(idd::GetLastMsg()).to_str().unwrap());
|
||||
'd' => {
|
||||
println!("Close device begin");
|
||||
idd::DeviceClose(h_sw_device);
|
||||
h_sw_device = invalid_device;
|
||||
} else {
|
||||
println!("Create device done");
|
||||
println!("Close device done");
|
||||
}
|
||||
'1' => plug_in(0, 0),
|
||||
'2' => plug_in(1, 0),
|
||||
'3' => plug_in(2, 0),
|
||||
'4' => plug_out(0),
|
||||
'5' => plug_out(1),
|
||||
'6' => plug_out(2),
|
||||
_ => {}
|
||||
}
|
||||
'd' => {
|
||||
println!("Close device begin");
|
||||
idd::DeviceClose(h_sw_device);
|
||||
h_sw_device = invalid_device;
|
||||
println!("Close device done");
|
||||
}
|
||||
'1' => plug_in(0, 0),
|
||||
'2' => plug_in(1, 0),
|
||||
'3' => plug_in(2, 0),
|
||||
'4' => plug_out(0),
|
||||
'5' => plug_out(1),
|
||||
'6' => plug_out(2),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
idd::DeviceClose(h_sw_device);
|
||||
idd::DeviceClose(h_sw_device);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,3 +42,6 @@ mod tray;
|
||||
|
||||
#[cfg(windows)]
|
||||
pub mod clipboard_file;
|
||||
|
||||
#[cfg(all(windows, feature = "with_rc"))]
|
||||
pub mod rc;
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Specify the Windows subsystem to eliminate console window.
|
||||
// Requires Rust 1.18.
|
||||
//#![windows_subsystem = "windows"]
|
||||
#![windows_subsystem = "windows"]
|
||||
|
||||
use hbb_common::log;
|
||||
use librustdesk::*;
|
||||
@ -104,6 +104,10 @@ fn main() {
|
||||
"".to_owned()
|
||||
));
|
||||
return;
|
||||
} else if args[0] == "--extract" {
|
||||
#[cfg(feature = "with_rc")]
|
||||
hbb_common::allow_err!(crate::rc::extract_resources(&args[1]));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if args[0] == "--remove" {
|
||||
|
@ -10,7 +10,6 @@ use std::io::prelude::*;
|
||||
use std::{
|
||||
ffi::OsString,
|
||||
fs, io, mem,
|
||||
path::Path,
|
||||
sync::{Arc, Mutex},
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
@ -856,7 +855,7 @@ fn get_install_info_with_subkey(subkey: String) -> (String, String, String, Stri
|
||||
}
|
||||
|
||||
pub fn update_me() -> ResultType<()> {
|
||||
let (_, _, _, exe) = get_install_info();
|
||||
let (_, path, _, exe) = get_install_info();
|
||||
let src_exe = std::env::current_exe()?.to_str().unwrap_or("").to_owned();
|
||||
let cmds = format!(
|
||||
"
|
||||
@ -865,12 +864,14 @@ pub fn update_me() -> ResultType<()> {
|
||||
taskkill /F /IM {broker_exe}
|
||||
taskkill /F /IM {app_name}.exe
|
||||
copy /Y \"{src_exe}\" \"{exe}\"
|
||||
\"{src_exe}\" --extract \"{path}\"
|
||||
sc start {app_name}
|
||||
{lic}
|
||||
",
|
||||
src_exe = src_exe,
|
||||
exe = exe,
|
||||
broker_exe = crate::ui::win_privacy::INJECTED_PROCESS_EXE,
|
||||
path = path,
|
||||
app_name = crate::get_app_name(),
|
||||
lic = register_licence(),
|
||||
);
|
||||
@ -1023,6 +1024,7 @@ chcp 65001
|
||||
md \"{path}\"
|
||||
copy /Y \"{src_exe}\" \"{exe}\"
|
||||
copy /Y \"{ORIGIN_PROCESS_EXE}\" \"{path}\\{broker_exe}\"
|
||||
\"{src_exe}\" --extract \"{path}\"
|
||||
reg add {subkey} /f
|
||||
reg add {subkey} /f /v DisplayIcon /t REG_SZ /d \"{exe}\"
|
||||
reg add {subkey} /f /v DisplayName /t REG_SZ /d \"{app_name}\"
|
||||
|
38
src/rc.rs
Normal file
38
src/rc.rs
Normal file
@ -0,0 +1,38 @@
|
||||
use hbb_common::{bail, ResultType};
|
||||
use std::{
|
||||
fs::{self, File},
|
||||
io::prelude::*,
|
||||
path::Path,
|
||||
};
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn extract_resources(root_path: &str) -> ResultType<()> {
|
||||
let mut resources: Vec<(&str, &[u8])> = Vec::new();
|
||||
resources.push((outfile_4, &outdata_4));
|
||||
do_extract(root_path, resources)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn do_extract(root_path: &str, resources: Vec<(&str, &[u8])>) -> ResultType<()> {
|
||||
let mut root_path = root_path.replace("\\", "/");
|
||||
if !root_path.ends_with('/') {
|
||||
root_path.push('/');
|
||||
}
|
||||
let root_path = Path::new(&root_path);
|
||||
for (outfile, data) in resources {
|
||||
let outfile_path = root_path.join(outfile);
|
||||
match outfile_path.parent().and_then(|p| p.to_str()) {
|
||||
None => {
|
||||
bail!("Failed to get parent of {}", outfile_path.display());
|
||||
}
|
||||
Some(p) => {
|
||||
fs::create_dir_all(p)?;
|
||||
let mut of = File::create(outfile_path)?;
|
||||
of.write_all(data)?;
|
||||
of.flush()?;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
@ -24,8 +24,8 @@ use clipboard::{
|
||||
};
|
||||
use enigo::{self, Enigo, KeyboardControllable};
|
||||
use hbb_common::fs::{
|
||||
can_enable_overwrite_detection, get_string, new_send_confirm,
|
||||
DigestCheckResult, RemoveJobMeta, get_job,
|
||||
can_enable_overwrite_detection, get_job, get_string, new_send_confirm, DigestCheckResult,
|
||||
RemoveJobMeta,
|
||||
};
|
||||
use hbb_common::{
|
||||
allow_err,
|
||||
@ -48,7 +48,7 @@ use hbb_common::{config::TransferSerde, fs::TransferJobMeta};
|
||||
use crate::clipboard_file::*;
|
||||
use crate::{
|
||||
client::*,
|
||||
common::{self, check_clipboard, update_clipboard, ClipboardContext, CLIPBOARD_INTERVAL}
|
||||
common::{self, check_clipboard, update_clipboard, ClipboardContext, CLIPBOARD_INTERVAL},
|
||||
};
|
||||
|
||||
type Video = AssetPtr<video_destination>;
|
||||
@ -267,7 +267,8 @@ impl Handler {
|
||||
std::env::set_var("KEYBOARD_ONLY", "y"); // pass to rdev
|
||||
use rdev::{EventType::*, *};
|
||||
let func = move |evt: Event| {
|
||||
if !IS_IN.load(Ordering::SeqCst) || !SERVER_KEYBOARD_ENABLED.load(Ordering::SeqCst) {
|
||||
if !IS_IN.load(Ordering::SeqCst) || !SERVER_KEYBOARD_ENABLED.load(Ordering::SeqCst)
|
||||
{
|
||||
return;
|
||||
}
|
||||
let (key, down) = match evt.event_type {
|
||||
@ -1660,7 +1661,12 @@ impl Remote {
|
||||
Data::AddJob((id, path, to, file_num, include_hidden, is_remote)) => {
|
||||
let od = can_enable_overwrite_detection(self.handler.lc.read().unwrap().version);
|
||||
if is_remote {
|
||||
log::debug!("new write waiting job {}, write to {} from remote {}", id, to, path);
|
||||
log::debug!(
|
||||
"new write waiting job {}, write to {} from remote {}",
|
||||
id,
|
||||
to,
|
||||
path
|
||||
);
|
||||
let mut job = fs::TransferJob::new_write(
|
||||
id,
|
||||
path.clone(),
|
||||
@ -1708,15 +1714,27 @@ impl Remote {
|
||||
if let Some(job) = get_job(id, &mut self.write_jobs) {
|
||||
job.is_last_job = false;
|
||||
allow_err!(
|
||||
peer.send(&fs::new_send(id, job.remote.clone(), job.file_num, job.show_hidden))
|
||||
peer.send(&fs::new_send(
|
||||
id,
|
||||
job.remote.clone(),
|
||||
job.file_num,
|
||||
job.show_hidden
|
||||
))
|
||||
.await
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if let Some(job) = get_job(id, &mut self.read_jobs) {
|
||||
job.is_last_job = false;
|
||||
allow_err!(peer.send(&fs::new_receive(id, job.path.to_string_lossy().to_string(),
|
||||
job.file_num, job.files.clone())).await);
|
||||
allow_err!(
|
||||
peer.send(&fs::new_receive(
|
||||
id,
|
||||
job.path.to_string_lossy().to_string(),
|
||||
job.file_num,
|
||||
job.files.clone()
|
||||
))
|
||||
.await
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2024,6 +2042,9 @@ impl Remote {
|
||||
Some(message::Union::file_response(fr)) => {
|
||||
match fr.union {
|
||||
Some(file_response::Union::dir(fd)) => {
|
||||
#[cfg(windows)]
|
||||
let entries = fd.entries.to_vec();
|
||||
#[cfg(not(windows))]
|
||||
let mut entries = fd.entries.to_vec();
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user