mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
win,linux remove desktop wallpaper
Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
@@ -5,7 +5,9 @@ use desktop::Desktop;
|
||||
use hbb_common::config::CONFIG_OPTION_ALLOW_LINUX_HEADLESS;
|
||||
pub use hbb_common::platform::linux::*;
|
||||
use hbb_common::{
|
||||
allow_err, bail,
|
||||
allow_err,
|
||||
anyhow::anyhow,
|
||||
bail,
|
||||
config::Config,
|
||||
libc::{c_char, c_int, c_long, c_void},
|
||||
log,
|
||||
@@ -26,6 +28,7 @@ use std::{
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use users::{get_user_by_name, os::unix::UserExt};
|
||||
use wallpaper;
|
||||
|
||||
type Xdo = *const c_void;
|
||||
|
||||
@@ -1311,3 +1314,41 @@ NoDisplay=false
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub struct WallPaperRemover {
|
||||
old_path: String,
|
||||
old_path_dark: Option<String>, // ubuntu 22.04 light/dark theme have different uri
|
||||
}
|
||||
|
||||
impl WallPaperRemover {
|
||||
pub fn new() -> ResultType<Self> {
|
||||
let start = std::time::Instant::now();
|
||||
let old_path = wallpaper::get().map_err(|e| anyhow!(e.to_string()))?;
|
||||
let old_path_dark = wallpaper::get_dark().ok();
|
||||
if old_path.is_empty() && old_path_dark.clone().unwrap_or_default().is_empty() {
|
||||
bail!("already solid color");
|
||||
}
|
||||
wallpaper::set_from_path("").map_err(|e| anyhow!(e.to_string()))?;
|
||||
wallpaper::set_dark_from_path("").ok();
|
||||
log::info!(
|
||||
"created wallpaper remover, old_path:{:?}, old_path_dark:{:?}, elapsed:{:?}",
|
||||
old_path,
|
||||
old_path_dark,
|
||||
start.elapsed(),
|
||||
);
|
||||
Ok(Self {
|
||||
old_path,
|
||||
old_path_dark,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for WallPaperRemover {
|
||||
fn drop(&mut self) {
|
||||
allow_err!(wallpaper::set_from_path(&self.old_path).map_err(|e| anyhow!(e.to_string())));
|
||||
if let Some(old_path_dark) = &self.old_path_dark {
|
||||
allow_err!(wallpaper::set_dark_from_path(old_path_dark.as_str())
|
||||
.map_err(|e| anyhow!(e.to_string())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ use hbb_common::{
|
||||
message_proto::Resolution,
|
||||
sleep, timeout, tokio,
|
||||
};
|
||||
use std::process::{Command, Stdio};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
ffi::OsString,
|
||||
@@ -26,6 +27,7 @@ use std::{
|
||||
sync::{atomic::Ordering, Arc, Mutex},
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use wallpaper;
|
||||
use winapi::{
|
||||
ctypes::c_void,
|
||||
shared::{minwindef::*, ntdef::NULL, windef::*, winerror::*},
|
||||
@@ -2335,3 +2337,98 @@ fn get_license() -> Option<License> {
|
||||
}
|
||||
Some(lic)
|
||||
}
|
||||
|
||||
fn get_sid_of_user(username: &str) -> ResultType<String> {
|
||||
let mut output = Command::new("wmic")
|
||||
.args(&[
|
||||
"useraccount",
|
||||
"where",
|
||||
&format!("name='{}'", username),
|
||||
"get",
|
||||
"sid",
|
||||
"/value",
|
||||
])
|
||||
.creation_flags(CREATE_NO_WINDOW)
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()?
|
||||
.stdout
|
||||
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "Failed to open stdout"))?;
|
||||
let mut result = String::new();
|
||||
output.read_to_string(&mut result)?;
|
||||
let sid_start_index = result
|
||||
.find('=')
|
||||
.map(|i| i + 1)
|
||||
.ok_or(anyhow!("bad output format"))?;
|
||||
if sid_start_index > 0 && sid_start_index < result.len() + 1 {
|
||||
Ok(result[sid_start_index..].trim().to_string())
|
||||
} else {
|
||||
bail!("bad output format");
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WallPaperRemover {
|
||||
old_path: String,
|
||||
}
|
||||
|
||||
impl WallPaperRemover {
|
||||
pub fn new() -> ResultType<Self> {
|
||||
let start = std::time::Instant::now();
|
||||
if !Self::need_remove() {
|
||||
bail!("already solid color");
|
||||
}
|
||||
let old_path = match Self::get_recent_wallpaper() {
|
||||
Ok(old_path) => old_path,
|
||||
Err(e) => {
|
||||
log::info!("Failed to get recent wallpaper:{:?}, use fallback", e);
|
||||
wallpaper::get().map_err(|e| anyhow!(e.to_string()))?
|
||||
}
|
||||
};
|
||||
Self::set_wallpaper(None)?;
|
||||
log::info!(
|
||||
"created wallpaper remover, old_path:{:?}, elapsed:{:?}",
|
||||
old_path,
|
||||
start.elapsed(),
|
||||
);
|
||||
Ok(Self { old_path })
|
||||
}
|
||||
|
||||
fn get_recent_wallpaper() -> ResultType<String> {
|
||||
// SystemParametersInfoW may return %appdata%\Microsoft\Windows\Themes\TranscodedWallpaper, not real path and may not real cache
|
||||
// https://www.makeuseof.com/find-desktop-wallpapers-file-location-windows-11/
|
||||
// https://superuser.com/questions/1218413/write-to-current-users-registry-through-a-different-admin-account
|
||||
let (hkcu, sid) = if is_root() {
|
||||
let username = get_active_username();
|
||||
let sid = get_sid_of_user(&username)?;
|
||||
log::info!("username:{username}, sid:{sid}");
|
||||
(RegKey::predef(HKEY_USERS), format!("{}\\", sid))
|
||||
} else {
|
||||
(RegKey::predef(HKEY_CURRENT_USER), "".to_string())
|
||||
};
|
||||
let explorer_key = hkcu.open_subkey_with_flags(
|
||||
&format!(
|
||||
"{}Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Wallpapers",
|
||||
sid
|
||||
),
|
||||
KEY_READ,
|
||||
)?;
|
||||
Ok(explorer_key.get_value("BackgroundHistoryPath0")?)
|
||||
}
|
||||
|
||||
fn need_remove() -> bool {
|
||||
if let Ok(wallpaper) = wallpaper::get() {
|
||||
return !wallpaper.is_empty();
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn set_wallpaper(path: Option<String>) -> ResultType<()> {
|
||||
wallpaper::set_from_path(&path.unwrap_or_default()).map_err(|e| anyhow!(e.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for WallPaperRemover {
|
||||
fn drop(&mut self) {
|
||||
// If the old background is a slideshow, it will be converted into an image. AnyDesk does the same.
|
||||
allow_err!(Self::set_wallpaper(Some(self.old_path.clone())));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user