Fix local debug launch

Fix local debug launch
This commit is contained in:
陈大猫
2026-06-12 11:54:26 +08:00
committed by GitHub
parent 9e31d53bdd
commit babe06a944
3 changed files with 80 additions and 1 deletions

View File

@@ -172,9 +172,20 @@ const devServerUrl = process.env.VITE_DEV_SERVER_URL;
// Never treat a packaged app as "dev" even if the user has VITE_DEV_SERVER_URL set globally. // Never treat a packaged app as "dev" even if the user has VITE_DEV_SERVER_URL set globally.
const isDev = !app.isPackaged && !!devServerUrl; const isDev = !app.isPackaged && !!devServerUrl;
const effectiveDevServerUrl = isDev ? devServerUrl : undefined; const effectiveDevServerUrl = isDev ? devServerUrl : undefined;
if (isDev) {
app.setName("Netcatty Dev");
app.setPath("userData", path.join(app.getPath("userData"), "dev"));
}
const preload = path.join(__dirname, "preload.cjs"); const preload = path.join(__dirname, "preload.cjs");
const isMac = process.platform === "darwin"; const isMac = process.platform === "darwin";
const appIcon = path.join(__dirname, "../public/icon.png"); function resolveAppIconPath() {
const candidates = [
path.join(__dirname, "../dist/icon.png"),
path.join(__dirname, "../public/icon.png"),
];
return candidates.find((candidate) => fs.existsSync(candidate)) || candidates[0];
}
const appIcon = resolveAppIconPath();
const electronDir = __dirname; const electronDir = __dirname;
const APP_PROTOCOL_HEADERS = { const APP_PROTOCOL_HEADERS = {

View File

@@ -19,6 +19,7 @@
const fs = require("node:fs"); const fs = require("node:fs");
const path = require("node:path"); const path = require("node:path");
const crypto = require("node:crypto"); const crypto = require("node:crypto");
const { execFileSync } = require("node:child_process");
const LC_UUID = 0x1b; const LC_UUID = 0x1b;
const MH_MAGIC_64 = 0xfeedfacf; // thin 64-bit, little-endian on disk const MH_MAGIC_64 = 0xfeedfacf; // thin 64-bit, little-endian on disk
@@ -105,6 +106,23 @@ function patchMachOFile(file, uuid) {
return result; return result;
} }
function adHocSignExecutable(exePath, options = {}) {
const hostPlatform = options.hostPlatform || process.platform;
const execFile = options.execFileSync || execFileSync;
if (hostPlatform !== "darwin") {
console.warn(
`[afterPack] Skipping ad-hoc codesign for ${exePath}; host platform is ${hostPlatform}`,
);
return false;
}
execFile("codesign", ["--force", "--sign", "-", "--timestamp=none", exePath], {
stdio: ["ignore", "pipe", "pipe"],
});
return true;
}
/** @param {import('electron-builder').AfterPackContext} context */ /** @param {import('electron-builder').AfterPackContext} context */
async function afterPack(context) { async function afterPack(context) {
if (context.electronPlatformName !== "darwin") return; if (context.electronPlatformName !== "darwin") return;
@@ -137,6 +155,14 @@ async function afterPack(context) {
`${oldUuids.map((h) => formatUuid(Buffer.from(h, "hex"))).join(", ")} -> ${formatUuid(uuid)} ` + `${oldUuids.map((h) => formatUuid(Buffer.from(h, "hex"))).join(", ")} -> ${formatUuid(uuid)} ` +
`(${patched} slice(s), appId=${appId})`, `(${patched} slice(s), appId=${appId})`,
); );
// The official Developer ID signing step runs after afterPack and replaces
// this temporary signature. Local unsigned builds skip that step, so the
// patched executable still needs a valid ad-hoc signature or macOS kills it
// before Electron can start.
if (adHocSignExecutable(exePath)) {
console.log("[afterPack] Ad-hoc signed patched macOS executable for local unsigned builds");
}
} }
module.exports = afterPack; module.exports = afterPack;
@@ -145,3 +171,4 @@ module.exports.deriveUuid = deriveUuid;
module.exports.formatUuid = formatUuid; module.exports.formatUuid = formatUuid;
module.exports.patchMachOBuffer = patchMachOBuffer; module.exports.patchMachOBuffer = patchMachOBuffer;
module.exports.patchMachOFile = patchMachOFile; module.exports.patchMachOFile = patchMachOFile;
module.exports.adHocSignExecutable = adHocSignExecutable;

View File

@@ -2,6 +2,7 @@ const test = require("node:test");
const assert = require("node:assert/strict"); const assert = require("node:assert/strict");
const { const {
adHocSignExecutable,
deriveUuid, deriveUuid,
patchMachOBuffer, patchMachOBuffer,
} = require("./afterPackMacUuid.cjs"); } = require("./afterPackMacUuid.cjs");
@@ -115,3 +116,43 @@ test("patchMachOBuffer reports zero when there is no LC_UUID", () => {
const { patched } = patchMachOBuffer(buf, deriveUuid("com.netcatty.app")); const { patched } = patchMachOBuffer(buf, deriveUuid("com.netcatty.app"));
assert.equal(patched, 0); assert.equal(patched, 0);
}); });
test("adHocSignExecutable signs patched binaries on macOS hosts", () => {
const calls = [];
const didSign = adHocSignExecutable("/tmp/Netcatty.app/Contents/MacOS/Netcatty", {
hostPlatform: "darwin",
execFileSync: (bin, args, options) => {
calls.push({ bin, args, options });
},
});
assert.equal(didSign, true);
assert.deepEqual(calls, [
{
bin: "codesign",
args: [
"--force",
"--sign",
"-",
"--timestamp=none",
"/tmp/Netcatty.app/Contents/MacOS/Netcatty",
],
options: { stdio: ["ignore", "pipe", "pipe"] },
},
]);
});
test("adHocSignExecutable skips non-macOS hosts", () => {
let called = false;
const didSign = adHocSignExecutable("/tmp/Netcatty", {
hostPlatform: "linux",
execFileSync: () => {
called = true;
},
});
assert.equal(didSign, false);
assert.equal(called, false);
});