fix: remote printer, update install option (#11461)

* fix: remote printer, update install option

Signed-off-by: fufesou <linlong1266@gmail.com>

* Add comments

Signed-off-by: fufesou <linlong1266@gmail.com>

* Add comments

Signed-off-by: fufesou <linlong1266@gmail.com>

* Win, run_cmds, remove extra whitespace and newline

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
fufesou 2025-04-24 18:24:22 +08:00 committed by GitHub
parent 5c2538e7af
commit 279fb72a4f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 73 additions and 4 deletions

View file

@ -1979,7 +1979,7 @@ class __PrinterState extends State<_Printer> {
final installed = bind.mainIsInstalled();
// `is-printer-installed` may fail, but it's rare case.
// Add additional error message here if it's really needed.
final driver_installed =
final isPrinterInstalled =
bind.mainGetCommonSync(key: 'is-printer-installed') == 'true';
final List<Widget> children = [];
@ -1988,8 +1988,8 @@ class __PrinterState extends State<_Printer> {
} else {
children.addAll([
if (!installed) tipClientNotInstalled(),
if (installed && !driver_installed) tipPrinterNotInstalled(),
if (installed && driver_installed) tipReady()
if (installed && !isPrinterInstalled) tipPrinterNotInstalled(),
if (installed && isPrinterInstalled) tipReady()
]);
}
return _Card(title: 'Outgoing Print Jobs', children: children);

View file

@ -2438,6 +2438,16 @@ pub fn main_set_common(_key: String, _value: String) {
(false, err)
}
};
if success {
// Use `ipc` to notify the server process to update the install option in the registry.
// Because `install_update_printer()` may prompt for permissions, there is no need to prompt again here.
if let Err(e) = crate::ipc::set_install_option(
crate::platform::REG_NAME_INSTALL_PRINTER.to_string(),
"1".to_string(),
) {
log::error!("Failed to set install printer option: {}", e);
}
}
let data = HashMap::from([
("name", serde_json::json!("install-printer-res")),
("success", serde_json::json!(success)),

View file

@ -274,6 +274,7 @@ pub enum Data {
ClearTrustedDevices,
#[cfg(all(target_os = "windows", feature = "flutter"))]
PrinterData(Vec<u8>),
InstallOption(Option<(String, String)>),
}
#[tokio::main(flavor = "current_thread")]
@ -662,6 +663,23 @@ async fn handle(data: Data, stream: &mut Connection) {
Data::ClearTrustedDevices => {
Config::clear_trusted_devices();
}
Data::InstallOption(opt) => match opt {
Some((_k, _v)) => {
#[cfg(target_os = "windows")]
if let Err(e) = crate::platform::windows::update_install_option(&_k, &_v) {
log::error!(
"Failed to update install option \"{}\" to \"{}\", error: {}",
&_k,
&_v,
e
);
}
}
None => {
// `None` is usually used to get values.
// This branch is left blank for unification and further use.
}
},
_ => {}
}
}
@ -1277,6 +1295,16 @@ async fn handle_wayland_screencast_restore_token(
return Ok(None);
}
#[tokio::main(flavor = "current_thread")]
pub async fn set_install_option(k: String, v: String) -> ResultType<()> {
if let Ok(mut c) = connect(1000, "").await {
c.send(&&Data::InstallOption(Some((k, v)))).await?;
// do not put below before connect, because we need to check should_exit
c.next_timeout(1000).await.ok();
}
Ok(())
}
#[cfg(test)]
mod test {
use super::*;

View file

@ -76,7 +76,7 @@ pub const SET_FOREGROUND_WINDOW: &'static str = "SET_FOREGROUND_WINDOW";
const REG_NAME_INSTALL_DESKTOPSHORTCUTS: &str = "DESKTOPSHORTCUTS";
const REG_NAME_INSTALL_STARTMENUSHORTCUTS: &str = "STARTMENUSHORTCUTS";
const REG_NAME_INSTALL_PRINTER: &str = "PRINTER";
pub const REG_NAME_INSTALL_PRINTER: &str = "PRINTER";
pub fn get_focused_display(displays: Vec<DisplayInfo>) -> Option<usize> {
unsafe {
@ -1590,6 +1590,35 @@ pub fn get_license_from_exe_name() -> ResultType<CustomServer> {
get_custom_server_from_string(&exe)
}
pub fn check_update_printer_option() {
if !is_installed() {
return;
}
let app_name = crate::get_app_name();
if let Ok(b) = remote_printer::is_rd_printer_installed(&app_name) {
let v = if b { "1" } else { "0" };
if let Err(e) = update_install_option(REG_NAME_INSTALL_PRINTER, v) {
log::error!(
"Failed to update printer option \"{}\" to \"{}\", error: {}",
REG_NAME_INSTALL_PRINTER,
v,
e
);
}
}
}
// We can't directly use `RegKey::set_value` to update the registry value, because it will fail with `ERROR_ACCESS_DENIED`
// So we have to use `run_cmds` to update the registry value.
pub fn update_install_option(k: &str, v: &str) -> ResultType<()> {
let app_name = crate::get_app_name();
let ext = app_name.to_lowercase();
let cmds =
format!("chcp 65001 && reg add HKEY_CLASSES_ROOT\\.{ext} /f /v {k} /t REG_SZ /d \"{v}\"");
run_cmds(cmds, false, "update_install_option")?;
Ok(())
}
#[inline]
pub fn is_win_server() -> bool {
unsafe { is_windows_server() > 0 }

View file

@ -567,6 +567,8 @@ pub async fn start_server(is_server: bool, no_server: bool) {
crate::platform::try_kill_broker();
#[cfg(feature = "hwcodec")]
scrap::hwcodec::start_check_process();
#[cfg(target_os = "windows")]
crate::platform::check_update_printer_option();
crate::RendezvousMediator::start_all().await;
} else {
match crate::ipc::connect(1000, "").await {