mirror of https://github.com/ospab/ostp.git
Compare commits
2 Commits
bc61b47817
...
cf14a4243c
| Author | SHA1 | Date |
|---|---|---|
|
|
cf14a4243c | |
|
|
66368c9d0f |
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"target_version": "0.4.3",
|
||||
"target_version": "0.4.4",
|
||||
"branch": "master",
|
||||
"alpha_iteration": 0,
|
||||
"beta_iteration": 4
|
||||
"beta_iteration": 0
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1386,7 +1386,7 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
|
|||
|
||||
[[package]]
|
||||
name = "ostp"
|
||||
version = "0.4.3"
|
||||
version = "0.4.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64",
|
||||
|
|
@ -1409,7 +1409,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ostp-client"
|
||||
version = "0.4.3"
|
||||
version = "0.4.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64",
|
||||
|
|
@ -1440,7 +1440,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ostp-core"
|
||||
version = "0.4.3"
|
||||
version = "0.4.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
|
|
@ -1474,7 +1474,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ostp-server"
|
||||
version = "0.4.3"
|
||||
version = "0.4.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum",
|
||||
|
|
@ -1507,7 +1507,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ostp-tun"
|
||||
version = "0.4.3"
|
||||
version = "0.4.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"libc",
|
||||
|
|
@ -1519,7 +1519,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ostp-tun-helper"
|
||||
version = "0.4.3"
|
||||
version = "0.4.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ resolver = "2"
|
|||
[workspace.package]
|
||||
edition = "2021"
|
||||
license = "AGPL-3.0"
|
||||
version = "0.4.3"
|
||||
version = "0.4.4"
|
||||
|
||||
[workspace.dependencies]
|
||||
anyhow = "1.0"
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
# In Windows, build-name is used as the major, minor, and patch parts
|
||||
# of the product and file versions while build-number is used as the build suffix.
|
||||
version: 0.4.3+30
|
||||
version: 0.4.4+31
|
||||
|
||||
environment:
|
||||
sdk: ^3.11.4
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "ostp-gui",
|
||||
"private": true,
|
||||
"version": "0.4.3",
|
||||
"version": "0.4.4",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"tauri": "tauri",
|
||||
|
|
|
|||
|
|
@ -2665,7 +2665,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ostp-client"
|
||||
version = "0.4.3"
|
||||
version = "0.4.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.22.1",
|
||||
|
|
@ -2696,7 +2696,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ostp-core"
|
||||
version = "0.4.3"
|
||||
version = "0.4.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
|
|
@ -2713,7 +2713,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ostp-gui"
|
||||
version = "0.4.3"
|
||||
version = "0.4.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"json_comments",
|
||||
|
|
@ -2733,7 +2733,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ostp-tun"
|
||||
version = "0.4.3"
|
||||
version = "0.4.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"libc",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "ostp-gui"
|
||||
version = "0.4.3"
|
||||
version = "0.4.4"
|
||||
description = "OSTP desktop GUI"
|
||||
authors = ["ospab"]
|
||||
edition = "2021"
|
||||
|
|
|
|||
|
|
@ -849,14 +849,74 @@ fn xml_escape(s: &str) -> String {
|
|||
.replace('\'', "'")
|
||||
}
|
||||
|
||||
/// Whether the elevated-launch Scheduled Task already exists.
|
||||
/// Reverse of [`xml_escape`]. `&` must be undone last or `<` would
|
||||
/// come back as `<`.
|
||||
#[cfg(target_os = "windows")]
|
||||
fn helper_task_exists() -> bool {
|
||||
quiet_command("schtasks")
|
||||
.args(["/Query", "/TN", HELPER_TASK_NAME])
|
||||
fn xml_unescape(s: &str) -> String {
|
||||
s.replace(""", "\"")
|
||||
.replace("'", "'")
|
||||
.replace("<", "<")
|
||||
.replace(">", ">")
|
||||
.replace("&", "&")
|
||||
}
|
||||
|
||||
/// The exe path currently baked into the registered task, if any.
|
||||
///
|
||||
/// Queried as XML rather than `/FO LIST /V`: the list format's field labels are
|
||||
/// localized (on a Russian Windows "Task To Run" is "Задача для запуска"),
|
||||
/// whereas XML tag names are fixed. schtasks writes UTF-16LE with a BOM here,
|
||||
/// but tolerate UTF-8 in case that ever changes.
|
||||
#[cfg(target_os = "windows")]
|
||||
fn helper_task_command() -> Option<String> {
|
||||
let out = quiet_command("schtasks")
|
||||
.args(["/Query", "/TN", HELPER_TASK_NAME, "/XML"])
|
||||
.output()
|
||||
.map(|o| o.status.success())
|
||||
.unwrap_or(false)
|
||||
.ok()?;
|
||||
if !out.status.success() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let text = if out.stdout.starts_with(&[0xFF, 0xFE]) {
|
||||
let units: Vec<u16> = out.stdout[2..]
|
||||
.chunks_exact(2)
|
||||
.map(|c| u16::from_le_bytes([c[0], c[1]]))
|
||||
.collect();
|
||||
String::from_utf16_lossy(&units)
|
||||
} else {
|
||||
String::from_utf8_lossy(&out.stdout).into_owned()
|
||||
};
|
||||
|
||||
let start = text.find("<Command>")? + "<Command>".len();
|
||||
let end = text[start..].find("</Command>")? + start;
|
||||
Some(xml_unescape(text[start..end].trim()))
|
||||
}
|
||||
|
||||
/// Whether a task is registered AND still points at the exe we are about to run.
|
||||
///
|
||||
/// The path matters as much as the name. A task registered by a dev build (or
|
||||
/// by an install that has since moved) keeps its original `<Command>`, and
|
||||
/// `schtasks /Run` reports success merely for *accepting* the request — a task
|
||||
/// whose exe no longer exists fails asynchronously and silently. Trusting the
|
||||
/// name alone therefore bought a 60-second "Timeout connecting to helper" on
|
||||
/// every single connect, permanently, until the task was deleted by hand.
|
||||
/// Re-registering costs one consent prompt and fixes it for good.
|
||||
#[cfg(target_os = "windows")]
|
||||
fn helper_task_matches(exe: &std::path::Path) -> bool {
|
||||
let Some(registered) = helper_task_command() else {
|
||||
return false;
|
||||
};
|
||||
let registered = registered.trim().trim_matches('"');
|
||||
|
||||
// Canonicalize both sides when possible so `..`, short 8.3 names and
|
||||
// casing differences do not read as a mismatch. A missing file cannot be
|
||||
// canonicalized — which is itself a mismatch worth re-registering over.
|
||||
match (
|
||||
std::fs::canonicalize(registered),
|
||||
std::fs::canonicalize(exe),
|
||||
) {
|
||||
(Ok(a), Ok(b)) => a == b,
|
||||
_ => registered.eq_ignore_ascii_case(&exe.display().to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Register the Scheduled Task. This is the ONLY step that needs elevation, and
|
||||
|
|
@ -966,10 +1026,10 @@ fn install_helper_task(exe: &std::path::Path) -> anyhow::Result<()> {
|
|||
Err(e) => anyhow::bail!("could not run powershell to register the task: {e}"),
|
||||
}
|
||||
|
||||
if helper_task_exists() {
|
||||
if helper_task_matches(exe) {
|
||||
Ok(())
|
||||
} else {
|
||||
anyhow::bail!("schtasks reported success but the task is not present")
|
||||
anyhow::bail!("schtasks reported success but the task does not point at {}", exe.display())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -994,12 +1054,12 @@ fn launch_as_admin(exe: &std::path::PathBuf, token: &str, port: u16) -> anyhow::
|
|||
let wrote_args = std::fs::write(&args_file, payload.to_string()).is_ok();
|
||||
|
||||
if wrote_args {
|
||||
if !helper_task_exists() {
|
||||
if !helper_task_matches(exe) {
|
||||
if let Err(e) = install_helper_task(exe) {
|
||||
eprintln!("[OSTP] could not register the helper task ({e}); falling back to a direct elevated launch");
|
||||
}
|
||||
}
|
||||
if helper_task_exists() {
|
||||
if helper_task_matches(exe) {
|
||||
let run = quiet_command("schtasks")
|
||||
.args(["/Run", "/TN", HELPER_TASK_NAME])
|
||||
.output();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "ostp-gui",
|
||||
"version": "0.4.3",
|
||||
"version": "0.4.4",
|
||||
"identifier": "com.ospab.ostp",
|
||||
"build": {
|
||||
"frontendDist": "../src"
|
||||
|
|
|
|||
Loading…
Reference in New Issue