frpc-desktop/electron/api/frpc.ts
2023-11-27 15:03:25 +08:00

184 lines
4.2 KiB
TypeScript

import { app, ipcMain } from "electron";
import { Config, getConfig } from "../storage/config";
import { listProxy } from "../storage/proxy";
import { getVersionById } from "../storage/version";
const fs = require("fs");
const path = require("path");
const { exec, spawn } = require("child_process");
export let frpcProcess = null;
const runningCmd = {
commandPath: null,
configPath: null
};
// const getFrpc = (config: Config) => {
// getVersionById(config.currentVersion, (err, document) => {
// if (!err) {
// }
// });
// };
/**
* 获取选择版本的工作目录
* @param versionId 版本ID
* @param callback
*/
const getFrpcVersionWorkerPath = (
versionId: string,
callback: (workerPath: string) => void
) => {
getVersionById(versionId, (err2, version) => {
if (!err2) {
callback(version["frpcVersionPath"]);
}
});
};
/**
* 生成配置文件
*/
export const generateConfig = (
config: Config,
callback: (configPath: string) => void
) => {
listProxy((err3, proxys) => {
if (!err3) {
const proxyToml = proxys.map(m => {
let toml = `
[[proxies]]
name = "${m.name}"
type = "${m.type}"
localIP = "${m.localIp}"
localPort = ${m.localPort}
`;
switch (m.type) {
case "tcp":
toml += `remotePort = ${m.remotePort}`;
break;
case "http":
case "https":
toml += `customDomains=[${m.customDomains.map(m => `"${m}"`)}]`;
break;
default:
break;
}
return toml;
});
let toml = `
serverAddr = "${config.serverAddr}"
serverPort = ${config.serverPort}
auth.method = "${config.authMethod}"
auth.token = "${config.authToken}"
log.to = "frpc.log"
log.level = "debug"
log.maxDays = 3
webServer.addr = "127.0.0.1"
webServer.port = 57400
${proxyToml}
`;
// const configPath = path.join("frp.toml");
const filename = "frp.toml";
fs.writeFile(
path.join(app.getPath("userData"), filename), // 配置文件目录
toml, // 配置文件内容
{ flag: "w" },
err => {
if (!err) {
callback(filename);
}
}
);
}
});
};
/**
* 启动frpc子进程
* @param cwd
* @param commandPath
* @param configPath
*/
const startFrpcProcess = (commandPath: string, configPath: string) => {
const command = `${commandPath} -c ${configPath}`;
frpcProcess = spawn(command, {
cwd: app.getPath("userData"),
shell: true
});
runningCmd.commandPath = commandPath;
runningCmd.configPath = configPath;
frpcProcess.stdout.on("data", data => {
console.log(`命令输出: ${data}`);
});
frpcProcess.stdout.on("error", data => {
console.log(`执行错误: ${data}`);
frpcProcess.kill("SIGINT");
});
};
export const reloadFrpcProcess = () => {
if (frpcProcess && !frpcProcess.killed) {
getConfig((err1, config) => {
if (!err1) {
if (config) {
generateConfig(config, configPath => {
const command = `${runningCmd.commandPath} reload -c ${configPath}`;
console.log("重启", command);
exec(command, {
cwd: app.getPath("userData"),
shell: true
});
});
}
}
});
}
};
export const initFrpcApi = () => {
ipcMain.handle("frpc.running", async (event, args) => {
if (!frpcProcess) {
return false;
} else {
return !frpcProcess.killed;
}
});
ipcMain.on("frpc.start", async (event, args) => {
getConfig((err1, config) => {
if (!err1) {
if (config) {
getFrpcVersionWorkerPath(
config.currentVersion,
(frpcVersionPath: string) => {
generateConfig(config, configPath => {
startFrpcProcess(
path.join(frpcVersionPath, "frpc"),
configPath
);
});
}
);
} else {
event.reply(
"Home.frpc.start.error.hook",
"请先前往设置页面,修改配置后再启动"
);
}
}
});
});
ipcMain.on("frpc.stop", () => {
if (frpcProcess && !frpcProcess.killed) {
console.log("关闭");
frpcProcess.kill();
}
});
};