cicy-desktop 2.1.104 → 2.1.105
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/sidecar/docker.js +39 -21
package/package.json
CHANGED
package/src/sidecar/docker.js
CHANGED
|
@@ -428,36 +428,54 @@ async function installDocker({ emit, dest } = {}) {
|
|
|
428
428
|
await launchElevated(target, ["install", "--quiet", "--accept-license"], { emit: e });
|
|
429
429
|
}
|
|
430
430
|
|
|
431
|
-
// Run an admin-manifest exe (Docker Desktop
|
|
432
|
-
//
|
|
433
|
-
//
|
|
434
|
-
//
|
|
435
|
-
//
|
|
436
|
-
//
|
|
437
|
-
//
|
|
438
|
-
|
|
439
|
-
function launchElevated(exe, args, { emit } = {}) {
|
|
431
|
+
// Run an admin-manifest exe (the Docker Desktop installer) ELEVATED + in the
|
|
432
|
+
// user's INTERACTIVE session so its GUI is visible. A plain spawn fails (740,
|
|
433
|
+
// no UAC). The reliable method on these machines (verified) is a one-shot
|
|
434
|
+
// scheduled task with /rl HIGHEST /it: it runs with the built-in Administrator's
|
|
435
|
+
// elevated token (no UAC prompt) in the logged-on session, and — unlike
|
|
436
|
+
// cscript/VBS ShellExecute "runas" — isn't blocked by 360. cscript is kept only
|
|
437
|
+
// as a last-ditch fallback.
|
|
438
|
+
function elevateViaTask(exe, args) {
|
|
440
439
|
return new Promise((resolve) => {
|
|
440
|
+
try {
|
|
441
|
+
const user = process.env["USERNAME"] || "Administrator";
|
|
442
|
+
const stamp = `${process.pid}${Math.floor(Math.random() * 1e6)}`;
|
|
443
|
+
const tn = `cicy-elevate-${stamp}`;
|
|
444
|
+
// A wrapper .cmd in a no-space temp path avoids schtasks /tr quoting hell;
|
|
445
|
+
// the .cmd itself quotes the (space-containing) exe path.
|
|
446
|
+
const cmdPath = path.join(os.tmpdir(), `${tn}.cmd`);
|
|
447
|
+
const line = `"${exe}"` + (args.length ? " " + args.map((a) => (/\s/.test(a) ? `"${a}"` : a)).join(" ") : "");
|
|
448
|
+
fs.writeFileSync(cmdPath, `@echo off\r\n${line}\r\n`, "utf8");
|
|
449
|
+
const sch = (a, cb) => execFile("schtasks", a, { windowsHide: true }, cb);
|
|
450
|
+
sch(["/create", "/tn", tn, "/tr", cmdPath, "/sc", "ONCE", "/st", "00:00", "/rl", "HIGHEST", "/ru", user, "/it", "/f"], (err) => {
|
|
451
|
+
if (err) return resolve(false);
|
|
452
|
+
sch(["/run", "/tn", tn], (rerr) => {
|
|
453
|
+
// clean the task + wrapper after a delay (installer keeps running).
|
|
454
|
+
setTimeout(() => { sch(["/delete", "/tn", tn, "/f"], () => {}); try { fs.unlinkSync(cmdPath); } catch {} }, 30000);
|
|
455
|
+
resolve(!rerr);
|
|
456
|
+
});
|
|
457
|
+
});
|
|
458
|
+
} catch { resolve(false); }
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
function launchElevated(exe, args, { emit } = {}) {
|
|
463
|
+
return new Promise(async (resolve) => {
|
|
464
|
+
// 1) Preferred: scheduled task /rl HIGHEST (elevated, interactive, 360-safe).
|
|
465
|
+
if (await elevateViaTask(exe, args)) return resolve(true);
|
|
466
|
+
// 2) Fallback: cscript/VBS ShellExecute "runas" (shows a UAC prompt).
|
|
441
467
|
try {
|
|
442
468
|
const vbs = path.join(os.tmpdir(), "cicy-docker-elevate.vbs");
|
|
443
469
|
const argStr = args.join(" ").replace(/"/g, '""');
|
|
444
470
|
const exeEsc = String(exe).replace(/"/g, '""');
|
|
445
|
-
|
|
446
|
-
fs.writeFileSync(vbs,
|
|
447
|
-
`Set s = CreateObject("Shell.Application")\r\n` +
|
|
448
|
-
`s.ShellExecute "${exeEsc}", "${argStr}", "", "runas", 1\r\n`,
|
|
449
|
-
"utf8");
|
|
471
|
+
fs.writeFileSync(vbs, `Set s = CreateObject("Shell.Application")\r\ns.ShellExecute "${exeEsc}", "${argStr}", "", "runas", 1\r\n`, "utf8");
|
|
450
472
|
const child = spawn("cscript", ["//nologo", vbs], { windowsHide: true, detached: true, stdio: "ignore" });
|
|
451
|
-
let done = false;
|
|
452
|
-
const fin = (ok) => { if (done) return; done = true; resolve(ok); };
|
|
473
|
+
let done = false; const fin = (ok) => { if (!done) { done = true; resolve(ok); } };
|
|
453
474
|
child.on("error", () => {
|
|
454
|
-
// cscript missing/blocked → best-effort direct spawn (works if elevated).
|
|
455
475
|
try {
|
|
456
|
-
emit && emit({ phase: "install-docker", status: "running", message: "
|
|
476
|
+
emit && emit({ phase: "install-docker", status: "running", message: "提权方式受限,尝试直接启动安装包…" });
|
|
457
477
|
const c2 = spawn(exe, args, { windowsHide: false, detached: true, stdio: "ignore" });
|
|
458
|
-
c2.on("error", () => fin(false));
|
|
459
|
-
c2.on("spawn", () => fin(true));
|
|
460
|
-
c2.on("exit", () => fin(true));
|
|
478
|
+
c2.on("error", () => fin(false)); c2.on("spawn", () => fin(true)); c2.on("exit", () => fin(true));
|
|
461
479
|
} catch { fin(false); }
|
|
462
480
|
});
|
|
463
481
|
child.on("exit", () => fin(true));
|