Fix asset inventory update
build-windows / build-hello-agent-x64 (push) Successful in 6m6s
build-windows / sign-hello-agent-x64 (push) Successful in 6s
build-windows / validate-hello-agent-x64 (push) Successful in 7s

This commit is contained in:
2026-05-09 11:32:12 +02:00
parent e815776329
commit 8025f8558a
2 changed files with 30 additions and 6 deletions
+24 -4
View File
@@ -57,6 +57,13 @@ struct InfoUploaded {
last_uploaded: Option<Instant>,
id: String,
username: Option<String>,
// hello-agent local patch: tracks whether the most recent successful
// sysinfo upload carried the `inventory` key. The CMDB collector
// (hello-agent's `inventory.rs`) runs on a background thread and can
// finish *after* the first sysinfo tick has already fired; without
// this flag the loop would never re-upload because `uploaded == true`
// and `username` is unchanged. Re-apply on vendor resync.
had_inventory: bool,
}
impl Default for InfoUploaded {
@@ -67,18 +74,20 @@ impl Default for InfoUploaded {
last_uploaded: None,
id: "".to_owned(),
username: None,
had_inventory: false,
}
}
}
impl InfoUploaded {
fn uploaded(url: String, id: String, username: String) -> Self {
fn uploaded(url: String, id: String, username: String, had_inventory: bool) -> Self {
Self {
uploaded: true,
url,
last_uploaded: None,
id,
username: Some(username),
had_inventory,
}
}
}
@@ -126,9 +135,18 @@ async fn start_hbbs_sync_async() {
// we may not be able to get the username before login after the next restart.
let mut v = crate::get_sysinfo();
let sys_username = v["username"].as_str().unwrap_or_default().to_string();
// hello-agent local patch: the inventory collector is async
// (PowerShell + WMI + ipify, see `inventory::collect_inventory`)
// and routinely finishes after the first sysinfo tick. When
// INVENTORY transitions from empty → populated we need to
// re-upload, even though `uploaded == true` and the username
// hasn't changed. Re-apply on vendor resync.
let inventory_now_available = !config::INVENTORY.read().unwrap().is_empty();
// Though the username comparison is only necessary on Windows,
// we still keep the comparison on other platforms for consistency.
let need_upload = (!info_uploaded.uploaded || info_uploaded.username.as_ref() != Some(&sys_username)) &&
let need_upload = (!info_uploaded.uploaded
|| info_uploaded.username.as_ref() != Some(&sys_username)
|| (inventory_now_available && !info_uploaded.had_inventory)) &&
info_uploaded.last_uploaded.map(|x| x.elapsed() >= UPLOAD_SYSINFO_TIMEOUT).unwrap_or(true);
if need_upload {
v["version"] = json!(crate::VERSION);
@@ -158,9 +176,11 @@ async fn start_hbbs_sync_async() {
// the `inventory` key, identical to a vanilla rustdesk
// install.
let inventory = config::INVENTORY.read().unwrap().clone();
let mut had_inventory = false;
if !inventory.is_empty() {
if let Ok(inv_v) = serde_json::from_str::<Value>(&inventory) {
v["inventory"] = inv_v;
had_inventory = true;
}
}
let ab_name = Config::get_option(keys::OPTION_PRESET_ADDRESS_BOOK_NAME);
@@ -232,7 +252,7 @@ async fn start_hbbs_sync_async() {
}
};
if samever {
info_uploaded = InfoUploaded::uploaded(url.clone(), id.clone(), sys_username);
info_uploaded = InfoUploaded::uploaded(url.clone(), id.clone(), sys_username, had_inventory);
log::info!("sysinfo not changed, skip upload");
continue;
}
@@ -241,7 +261,7 @@ async fn start_hbbs_sync_async() {
match crate::post_request(url.replace("heartbeat", "sysinfo"), v, "").await {
Ok(x) => {
if x == "SYSINFO_UPDATED" {
info_uploaded = InfoUploaded::uploaded(url.clone(), id.clone(), sys_username);
info_uploaded = InfoUploaded::uploaded(url.clone(), id.clone(), sys_username, had_inventory);
log::info!("sysinfo updated");
if !hash.is_empty() {
config::Status::set("sysinfo_hash", hash);