Skip to content

Commit 6fcbd48

Browse files
committed
build(desktop-backend): 打包后端时注入版本信息并同步 native 资源
- 从 desktop/package.json 读取版本号并生成 PyInstaller version-file - 打包后复制 native 目录到 resources/backend/native,避免 onefile 临时目录依赖 - 将 pyproject.toml 复制到 backend 资源目录,补齐运行时项目标记 - 更新 .gitignore,忽略 backend/native 与 backend/pyproject.toml 打包产物
1 parent d2c8857 commit 6fcbd48

2 files changed

Lines changed: 89 additions & 1 deletion

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ pnpm-lock.yaml
4444
/desktop/resources/ui/*
4545
!/desktop/resources/ui/.gitkeep
4646
/desktop/resources/backend/*.exe
47+
/desktop/resources/backend/native/*
48+
/desktop/resources/backend/pyproject.toml
4749
!/desktop/resources/backend/.gitkeep
4850
/desktop/resources/icon.ico
4951

desktop/scripts/build-backend.cjs

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,63 @@ fs.mkdirSync(distDir, { recursive: true });
1313
fs.mkdirSync(workDir, { recursive: true });
1414
fs.mkdirSync(specDir, { recursive: true });
1515

16+
function parseVersionTuple(rawVersion) {
17+
const nums = String(rawVersion || "")
18+
.split(/[^\d]+/)
19+
.map((x) => Number.parseInt(x, 10))
20+
.filter((n) => Number.isInteger(n) && n >= 0);
21+
while (nums.length < 4) nums.push(0);
22+
return nums.slice(0, 4);
23+
}
24+
25+
function buildVersionInfoText(versionTuple, versionDot) {
26+
const [a, b, c, d] = versionTuple;
27+
return `# UTF-8
28+
VSVersionInfo(
29+
ffi=FixedFileInfo(
30+
filevers=(${a}, ${b}, ${c}, ${d}),
31+
prodvers=(${a}, ${b}, ${c}, ${d}),
32+
mask=0x3f,
33+
flags=0x0,
34+
OS=0x4,
35+
fileType=0x1,
36+
subtype=0x0,
37+
date=(0, 0)
38+
),
39+
kids=[
40+
StringFileInfo([
41+
StringTable(
42+
'080404B0',
43+
[StringStruct('CompanyName', 'LifeArchiveProject'),
44+
StringStruct('FileDescription', 'WeFlow'),
45+
StringStruct('FileVersion', '${versionDot}'),
46+
StringStruct('InternalName', 'weflow'),
47+
StringStruct('LegalCopyright', 'github.com/hicccc77/WeFlow'),
48+
StringStruct('OriginalFilename', 'weflow.exe'),
49+
StringStruct('ProductName', 'WeFlow'),
50+
StringStruct('ProductVersion', '${versionDot}')])
51+
]),
52+
VarFileInfo([VarStruct('Translation', [2052, 1200])])
53+
]
54+
)
55+
`;
56+
}
57+
1658
const nativeDir = path.join(repoRoot, "src", "wechat_decrypt_tool", "native");
1759
const addData = `${nativeDir};wechat_decrypt_tool/native`;
60+
const projectToml = path.join(repoRoot, "pyproject.toml");
61+
62+
const desktopPackageJsonPath = path.join(repoRoot, "desktop", "package.json");
63+
let desktopVersion = "1.3.0";
64+
try {
65+
const pkg = JSON.parse(fs.readFileSync(desktopPackageJsonPath, { encoding: "utf8" }));
66+
const v = String(pkg?.version || "").trim();
67+
if (v) desktopVersion = v;
68+
} catch {}
69+
const versionTuple = parseVersionTuple(desktopVersion);
70+
const versionDot = versionTuple.join(".");
71+
const versionFilePath = path.join(workDir, "weflow-version.txt");
72+
fs.writeFileSync(versionFilePath, buildVersionInfoText(versionTuple, versionDot), { encoding: "utf8" });
1873

1974
const args = [
2075
"run",
@@ -30,11 +85,42 @@ const args = [
3085
workDir,
3186
"--specpath",
3287
specDir,
88+
"--version-file",
89+
versionFilePath,
3390
"--add-data",
3491
addData,
3592
entry,
3693
];
3794

3895
const r = spawnSync("uv", args, { cwd: repoRoot, stdio: "inherit" });
39-
process.exit(r.status ?? 1);
96+
if ((r.status ?? 1) !== 0) {
97+
process.exit(r.status ?? 1);
98+
}
99+
100+
// Keep a stable external native folder for packaged runtime to avoid relying on
101+
// onefile temp extraction paths when wcdb_api.dll performs environment checks.
102+
const packagedNativeDir = path.join(distDir, "native");
103+
try {
104+
fs.rmSync(packagedNativeDir, { recursive: true, force: true });
105+
} catch {}
106+
fs.mkdirSync(packagedNativeDir, { recursive: true });
107+
108+
for (const name of fs.readdirSync(nativeDir)) {
109+
const src = path.join(nativeDir, name);
110+
const dst = path.join(packagedNativeDir, name);
111+
try {
112+
if (fs.statSync(src).isFile()) {
113+
fs.copyFileSync(src, dst);
114+
}
115+
} catch {}
116+
}
117+
118+
// Provide the project marker next to packaged backend resources.
119+
if (fs.existsSync(projectToml)) {
120+
try {
121+
fs.copyFileSync(projectToml, path.join(distDir, "pyproject.toml"));
122+
} catch {}
123+
}
124+
125+
process.exit(0);
40126

0 commit comments

Comments
 (0)