返回 DeepSeek-Reasonix
appIdentity.ts
根目录 / desktop / electron / src / main / appIdentity.ts
1 import { lstatSync } from "node:fs";
2 import { win32 } from "node:path";
3 import type { AppDetailsOptions, BrowserWindow } from "electron";
4
5 // Share the launcher's identity without grouping with old or current Studio.
6 // internal/appidentity/electron_identity_test.go guards the Go/JS contract.
7
8 export const APP_USER_MODEL_ID = "io.reasonix.desktop";
9
10 // Applied at module load: the ID must be in place before the first window
11 // exists, and Windows ignores the call on other platforms.
12 export function applyAppUserModelId(target: Pick<typeof import("electron").app, "setAppUserModelId">, platform: NodeJS.Platform): void {
13 if (platform === "win32") target.setAppUserModelId(APP_USER_MODEL_ID);
14 }
15
16 interface WindowCreationEvents {
17 on(event: "browser-window-created", listener: (event: unknown, window: Pick<BrowserWindow, "setAppDetails">) => void): unknown;
18 }
19
20 function isRegularFile(path: string): boolean {
21 try { return lstatSync(path).isFile(); } catch { return false; }
22 }
23
24 export function windowsTaskbarDetails(executable: string, isFile = isRegularFile): AppDetailsOptions | undefined {
25 if (!win32.isAbsolute(executable)) return undefined;
26 const appDir = win32.dirname(executable);
27 if (win32.basename(appDir).toLowerCase() !== "app") return undefined;
28 const releaseDir = win32.dirname(appDir);
29 const versioned = win32.basename(win32.dirname(releaseDir)).toLowerCase() === "versions"
30 && /^v[0-9]+(?:\.[0-9]+){1,3}(?:-[0-9A-Za-z.-]+)?$/.test(win32.basename(releaseDir));
31 const root = versioned ? win32.dirname(win32.dirname(releaseDir)) : releaseDir;
32 const launcher = ["Reasonix.exe", "reasonix-launcher.exe"].map(name => win32.join(root, name)).find(isFile);
33 if (!launcher) return undefined;
34 return {
35 appId: APP_USER_MODEL_ID,
36 appIconPath: launcher,
37 appIconIndex: 0,
38 relaunchCommand: `"${launcher}"`,
39 relaunchDisplayName: "Reasonix",
40 };
41 }
42
43 // An AppID alone makes Explorer pin the versioned Electron executable. Stamp
44 // every window before it is shown so new pins also survive version retention.
45 export function registerTaskbarRelaunch(target: WindowCreationEvents, platform: NodeJS.Platform, executable: string, packaged: boolean, isFile = isRegularFile): void {
46 if (platform !== "win32" || !packaged) return;
47 const details = windowsTaskbarDetails(executable, isFile);
48 if (details) target.on("browser-window-created", (_event, window) => window.setAppDetails(details));
49 }
50
50 lines TYPESCRIPT