修改 导入utils模块出错问题

This commit is contained in:
weike 2024-05-29 14:19:21 +08:00 committed by wangpenglong
parent f1b51992ba
commit 7cab1b48ae
3 changed files with 387 additions and 14 deletions

View File

@ -28,7 +28,7 @@ import { KeyCode } from 'vs/base/common/keyCodes';
import { mainWindow } from 'vs/base/browser/window';
import { ThemeIcon } from 'vs/base/common/themables';
import { Codicon } from 'vs/base/common/codicons';
import { get_g_index_url, configDir } from 'vs/platform/issue/electron-main/utils';
import * as utils from 'vs/platform/issue/electron-main/utils';
import { addDisposableListener, EventType, getWindow, getWindowId, hide, show } from 'vs/base/browser/dom';
import { isDisposable } from 'vs/base/common/lifecycle';
@ -239,8 +239,8 @@ class deployWindow {
preElement!.innerHTML = "";
const messageData = {
url: get_g_index_url(),
dst: configDir()
url: utils.get_g_index_url(),
dst: utils.configDir()
}
//联网检查是否有合适的文件
ipcRenderer.send("kylinide.installWizard.checkInstall", messageData);
@ -305,9 +305,12 @@ class deployWindow {
dTpreElement!.innerHTML = '';
let dTformattedDoc = '';
let progressViews = document.getElementsByClassName("progress-view") as HTMLCollectionOf<HTMLProgressElement>;
progressViews[0].value = (this.progressNum / this.extInstallState.size) * 100;
document.getElementsByClassName("progressinfo")[0].innerHTML = "安装进度:" + ((this.progressNum / this.extInstallState.size) * 100).toFixed(2) + "%";
console.log("progressNum:" + this.progressNum + " extInstallState.size:" + this.extInstallState.size)
if (this.extInstallState.size > 0) {
let progressViews = document.getElementsByClassName("progress-view") as HTMLCollectionOf<HTMLProgressElement>;
progressViews[0].value = (this.progressNum / this.extInstallState.size) * 100;
document.getElementsByClassName("progressinfo")[0].innerHTML = "安装进度:" + ((this.progressNum / this.extInstallState.size) * 100).toFixed(2) + "%";
}
for (const [key, value] of this.extInstallState) {
if (key === undefined) continue;
@ -527,7 +530,7 @@ class deployWindow {
console.log("onlineInstallArrayIndex:" + this.onlineInstallTabArrayIndex);
if (this.onlineInstallTabArray[this.onlineInstallTabArrayIndex] === "onlineInstallTab1") {
//获取radio的值
console.log("onlineInstallTab1");
let select = "local";
if (this.onlineUpdateConfigRadio && this.onlineUpdateConfigRadio instanceof HTMLInputElement && this.onlineUpdateConfigRadio.checked) {
select = "update"
@ -542,9 +545,11 @@ class deployWindow {
type: "configGetValue",
class: "install"
}
console.log("onlineInstallTab2");
ipcRenderer.send('kylinide.installWizard.init', data);
} else if (this.onlineInstallTabArray[this.onlineInstallTabArrayIndex] === "onlineInstallTab3") {
const checkboxForm = document.getElementById("checkboxForm");
console.log("onlineInstallTab3");
// 获取所有选中的复选框
let selectedCheckboxes = checkboxForm!.querySelectorAll('input[type="checkbox"]:checked');
let checkSelectedValues = [];
@ -622,10 +627,12 @@ class deployWindow {
ipcRenderer.send('kylinide.installWizard.init', { type: "writeJson", });
} else if (this.onlineInstallTabArray[this.onlineInstallTabArrayIndex] === "onlineInstallTab4") {
ipcRenderer.send('kylinide.installWizard.ok');
console.log("onlineInstallTab4");
this.removeAllListeners();
return;
}
if (this.onlineInstallTabArrayIndex < this.onlineInstallTabArray.length - 1) {
console.log("this.onlineInstallTabArrayIndex < this.onlineInstallTabArray.length - 1");
if (this.onlineInstallTabArrayIndex == 0) {
console.log("在线安装");
ipcRenderer.send("kylinide.installWizard.init", { type: "httpVerify" });
@ -645,6 +652,7 @@ class deployWindow {
// }
if (this.onlineInstallTabArray[this.onlineInstallTabArrayIndex] === "onlineInstallTab4") {
console.log("onlineInstallTab4 last");
this.prevBtn!.disabled = true;
this.nextBtn!.disabled = true;
this.nextBtn!.innerHTML = "确定";
@ -720,12 +728,18 @@ class deployWindow {
console.log('click nextStep');
this.nextPrev(1);
});
document.getElementById('cancel')?.addEventListener('click', () => {
console.log('cancel');
// ipcRenderer.removeAllListeners('kylinide.installWizard.msg');
ipcRenderer.send('kylinide.installWizard.msg.process', { type: "cancel" });
});
/**
* /
*/
document.getElementById("switchInstallOutput")?.addEventListener("click", () => {
// 切换显示和隐藏
console.log("switchInstallOutput clicked");
const logPreElement = document.getElementById("installLogPre");
const installPreElement = document.getElementById("detailInstallPre");
const extLogPreElement = document.getElementById("extInstallLogPre");
@ -1086,7 +1100,7 @@ class deployWindow {
extList: this.extList,
depList: this.depList,
script: obj,
dst: configDir()
dst: utils.configDir()
};
ipcRenderer.send("kylinide.installWizard.msg.process", installMsg);
}

View File

@ -109,6 +109,23 @@ export class DeployMainService implements IDeployMainService {
depList: string[] = [];
extList: string[] = [];
lastLogPosition: number = 0;
//文件监听;
installFsWatcher: fs.FSWatcher | null = null;
extlogFsWatcher: fs.FSWatcher | null = null;
pkglogFsWatcher: fs.FSWatcher | null = null;
//执行安装脚本的进程号;
installProcessId: ChildProcess | null = null;
cancelFlag = false;
flagPkexec = 0;
maxBackupFiles = 7;
lastExtLogPosition = 0;
logFile0 = "";
resultFile = "";
extLogFile0 = "";
controller = new AbortController();
constructor(
private userEnv: IProcessEnvironment,
@ -133,6 +150,10 @@ export class DeployMainService implements IDeployMainService {
this.localConfigDir = installUtils.localConfigPath();
this.installConfig = installUtils.installConfigDirPre();//installconfig
this.updateConfigDir = installUtils.installConfigDirPre() + "/" + installUtils.getDateDir();
this.logFile0 = this.installConfig + '/log/install.1.log';
this.resultFile = this.installConfig + '/resultFile';
this.extLogFile0 = this.installConfig + '/log/extInstall.1.log';
this.registerListeners();
}
@ -155,12 +176,348 @@ export class DeployMainService implements IDeployMainService {
this.closeWindow();
});
validatedIpcMain.on('kylinide.installWizard.msg.process', async (event, msg) => {
if (msg.type === 'installExt') {
const logFile0 = this.installConfig + '/log/extInstall.1.log';
if (!fs.existsSync(logFile0)) {
fs.mkdirSync(this.installConfig + "/log", { recursive: true });
}
try {
const installItem = this.extDownloadPath + msg.downloadDone;
const installCommand = "kylin-code --install-extension " + installItem;
if (this.installQueue.length === 0) {
this.installQueue.push({ installCommand, msg });
await this.executeNextInstall();
}
else {
this.installQueue.push({ installCommand, msg });
}
} catch (error) {
console.error(`执行出错: ${error.message}`);
}
}
else if (msg.type === 'installPkg') {
console.log("kylinide.installWizard.msg.process:installPkg");
const extlogFile = this.installConfig + '/log/extInstall.log';
this.backupLogFile(extlogFile)
const extlogFile0 = this.installConfig + '/log/extInstall.1.log';
fs.writeFileSync(extlogFile0, '');
if (this.depList.length === 0) {
const startDownloadExtMsg = {
type: "extDownloadInit",
}
if (this.DeployWindow)
this.DeployWindow.webContents.send("kylinide.installWizard.msg", startDownloadExtMsg);
this.lastExtLogPosition = 0;
fs.watch(this.extLogFile0, (eventType, filename) => {
if (eventType === 'change') {
// 获取文件的当前大小
const stats = fs.statSync(this.extLogFile0);
const currentSize = stats.size;
// 计算更新部分的大小
const updateSize = currentSize - this.lastExtLogPosition;
if (updateSize <= 0) return;
// 读取更新部分的内容
const buffer = Buffer.alloc(updateSize);
const fileDescriptor = fs.openSync(this.extLogFile0, 'r');
fs.readSync(fileDescriptor, buffer, 0, updateSize, this.lastExtLogPosition);
fs.closeSync(fileDescriptor);
// 将更新部分的内容转换为字符串并输出
const updatedContent = buffer.toString('utf8');
// 更新上一次读取的位置
this.lastExtLogPosition = currentSize;
const installMsg = {
type: "extInstallLogPre",
data: updatedContent
};
if (this.DeployWindow)
this.DeployWindow.webContents.send("kylinide.installWizard.msg", installMsg)
}
});
return;
}
this.lastLogPosition = 0;
this.lastExtLogPosition = 0;
const logFile = this.installConfig + '/log/install.log';
const resultFile = this.installConfig + '/resultFile';
const installFile = this.installConfig + '/install.sh';
const logFile0 = this.installConfig + '/log/install.1.log';
this.backupLogFile(logFile);
try {
fs.writeFileSync(resultFile, '');
fs.writeFileSync(installFile, '');
fs.writeFileSync(logFile0, '');
const installMsg = {
type: "depStartInstall",
depName: 'depStartInstall'
};
if (this.DeployWindow)
this.DeployWindow.webContents.send("kylinide.installWizard.msg", installMsg)
if (this.depList.length === 0) return;
this.depList.forEach((packageName) => {
const command = `apt-get install -y ${packageName} >> ${logFile0};\necho $? >> ${resultFile};\n`;
fs.appendFileSync(installFile, command);
});
this.executeScriptWithPkexec(installFile);
} catch (error) {
console.log(error);
}
}
else if (msg.type === 'installScript') {
if (msg.script['file_name'].endsWith(".js")) {
try {
await this.loadAndInvokeFunction(this.selectObject.dirPath + '/' + msg.script['file_name'], "main");
const scriptMsg = {
type: "scriptExecSucc",
depName: msg.script['file_name']
};
logger.info("脚本执行成功" + this.selectObject.dirPath + '/' + msg.script['file_name']);
if (this.DeployWindow)
this.DeployWindow.webContents.send("kylinide.installWizard.msg", scriptMsg)
} catch {
const scriptMsg = {
type: "scriptExecFail",
depName: msg.script['file_name']
};
logger.info("脚本执行失败" + this.selectObject.dirPath + '/' + msg.script['file_name']);
if (this.DeployWindow)
this.DeployWindow.webContents.send("kylinide.installWizard.msg", scriptMsg)
}
} else if (msg.script['file_name'].endsWith(".sh")) {
let command = "sh " + this.selectObject.dirPath + '/' + msg.script['file_name'];
// await executeCommand(command);
this.executeCommand(command).then(res => {
const scriptMsg = {
type: "scriptExecSucc",
depName: msg.script['file_name']
};
logger.info("脚本执行成功" + this.selectObject.dirPath + '/' + msg.script['file_name']);
if (this.DeployWindow)
this.DeployWindow.webContents.send("kylinide.installWizard.msg", scriptMsg)
}).catch(error => {
const scriptMsg = {
type: "scriptExecFail",
depName: msg.script['file_name']
};
logger.info("脚本执行失败" + this.selectObject.dirPath + '/' + msg.script['file_name']);
if (this.DeployWindow)
this.DeployWindow.webContents.send("kylinide.installWizard.msg", scriptMsg)
});
}
}
else if (msg.type == "cancel") {
//1.结束监听
//2.结束正在执行的进程,下载,插件安装,软件包安装
if (this.installProcessId && this.installProcessId.pid && this.installProcessId.exitCode == null && this.flagPkexec == 0) {
console.log("取消安装before");
// var killcommand = `pkexec sudo pkill -TERM -P ${installProcessId.pid}`;
var killcommand = `pkexec sudo pkill -f 'bash ${this.installConfig}/install.sh'`;
const sudokill = spawn(killcommand, { shell: true, stdio: 'inherit' });
sudokill.on('exit', (code, signal) => {
if (code == 127) {
console.log('授权失败', code);
logger.error("取消安装授权失败");
} else {
if (this.DeployWindow) {
this.DeployWindow.webContents.send("kylinide.installWizard.removeFileLister", { type: 'installFile' });
this.DeployWindow.webContents.send("kylinide.installWizard.removeFileLister", { type: 'extFile' });
this.DeployWindow.webContents.send("kylinide.installWizard.removeFileLister", { type: 'pkgFile' });
}
this.controller.abort();
this.installQueue.splice(0);
//结束插件下载及安装
if (this.DeployWindow) {
this.DeployWindow.webContents.send("kylinide.installWizard.cancelinstall", { type: "cancelinstall" });
}
}
console.log('kill Exit code:', code);
});
console.log("取消安装after");
} else {
if (this.DeployWindow) {
this.DeployWindow.webContents.send("kylinide.installWizard.removeFileLister", { type: 'installFile' });
this.DeployWindow.webContents.send("kylinide.installWizard.removeFileLister", { type: 'extFile' });
this.DeployWindow.webContents.send("kylinide.installWizard.removeFileLister", { type: 'pkgFile' });
}
this.controller.abort();
this.cancelFlag = true;
this.installQueue.splice(0);
//结束插件下载及安装
if (this.DeployWindow) {
this.DeployWindow.webContents.send("kylinide.installWizard.cancelinstall", { type: "cancelinstall" });
}
}
}
});
// validatedIpcMain.on('kylinide.installWizard.skipWizard', event => {
// logger.info("跳过操作");
// })
}
//#endregion
executeScriptWithPkexec(scriptPath: string) {
this.flagPkexec = 0;
console.log("executeScriptWithPkexec");
try {
const pkexecCommand = `pkexec sudo bash ${scriptPath}`;
this.installProcessId =
spawn(pkexecCommand, { shell: true, stdio: 'inherit' });
this.installProcessId.on('exit', (code, signal) => {
this.flagPkexec++;
console.log('Exit code:', code);
if (code == 127) {
//授权失败,结束安装。
if (this.DeployWindow) {
this.DeployWindow.webContents.send("kylinide.installWizard.Auth", { type: "pkgNotAuth" });
}
}
});
} catch (error) {
console.error(`执行脚本时出错: ${error.message}`);
// return false;
}
}
// 获取备份文件名
getBackupFileName(filePath: string, index: number) {
const path = require('path');
const extname = path.extname(filePath);
const basename = path.basename(filePath, extname);
return `${basename}.${index}${extname}`;
}
// 备份日志文件
backupLogFile(filePath: string) {
const path = require('path');
for (let i = this.maxBackupFiles - 1; i >= 0; i--) {
const currentFileName = i === 0 ? filePath : this.getBackupFileName(filePath, i);
const nextFileName = this.getBackupFileName(filePath, i + 1);
const currentFilePath = path.join(path.dirname(filePath), currentFileName);
const nextFilePath = path.join(path.dirname(filePath), nextFileName);
if (fs.existsSync(currentFilePath)) {
if (i === this.maxBackupFiles - 1) {
if (fs.existsSync(nextFileName))
fs.unlinkSync(nextFilePath);
}
fs.copyFileSync(currentFilePath, nextFilePath);
}
}
}
async executeNextInstall() {
if (this.installQueue.length === 0) {
return; // 队列为空,结束执行
}
if (this.cancelFlag) {
this.installQueue.splice(0);
return;
}
const { installCommand, msg } = this.installQueue[0];
try {
const extlogFile = this.installConfig + '/log/extInstall.1.log';
let ret: { stdout: string, stderr: string } = await this.spawnCommand(installCommand) as { stdout: string; stderr: string; };
if (ret.stdout)
fs.appendFileSync(extlogFile, ret.stdout);
// if (ret.stderr)
// fs.appendFileSync(extlogFile, ret.stderr);
const installMsg = {
type: "extInstalled",
extFileName: msg.downloadDone,
// extTotal: Object.keys(extMap).length,
extTotal: this.extList.length
};
if (this.DeployWindow) {
this.DeployWindow.webContents.send("kylinide.installWizard.msg", installMsg);
}
} catch (error) {
console.error(`执行出错: ${error.message}`);
const extlogFile = this.installConfig + '/log/extInstall.1.log';
fs.appendFileSync(extlogFile, installCommand);
fs.appendFileSync(extlogFile, '\n');
fs.appendFileSync(extlogFile, error.message);
fs.appendFileSync(extlogFile, '\n');
const installMsg = {
type: "extInstalledFail",
extFileName: msg.downloadDone,
extTotal: this.extList.length,
extName: msg.extName
};
if (this.DeployWindow) {
this.DeployWindow.webContents.send("kylinide.installWizard.msg", installMsg);
}
}
this.installQueue.shift(); // 执行完成后,将当前消息从队列中移除
await this.executeNextInstall(); // 继续执行下一个消息
}
spawnCommand(command: string) {
return new Promise((resolve, reject) => {
const child = spawn(command, { shell: true });
let stdout = '';
let stderr = '';
child.stdout.on('data', (data) => {
stdout += data.toString();
});
child.stderr.on('data', (data) => {
stderr += data.toString();
});
child.on('close', (code) => {
if (code === 0) {
resolve({ stdout, stderr });
} else {
reject(new Error(`Command failed with exit code ${code} `));
}
});
});
}
async executeCommand(command: string) {
return new Promise<void>((resolve, reject) => {
const { exec } = require('child_process');
exec(command, (error: any, stdout: any, stderr: any) => {
if (error) {
reject(error);
} else {
// console.log(`stdout: ${ stdout } `);
// console.error(`stderr1: ${ stderr } `);
resolve();
}
});
});
}
minWindow() {
if (this.DeployWindow) {
this.DeployWindow.minimize();
@ -226,7 +583,7 @@ export class DeployMainService implements IDeployMainService {
validatedIpcMain.on('kylinide.installWizard.init', async (event, msg) => {
console.log("main on kylinide.installWizard.init");
let selectPageShow = 0;
let message: string;
let message: string = "";
if (msg.type === "httpVerify") {
this.checkHttp().then(async res => {
console.log("ipc main kylinide.installWizard.init httpVerify");
@ -275,7 +632,7 @@ export class DeployMainService implements IDeployMainService {
type: "error",
title: "配置文件检查",
buttons: ["OK"],
detail: `点击【OK】按钮后将跳过此引导步骤请根据开发需要自行下载插件、安装软件依赖。具体信息请查看日志${installConfig}/log/instguide.log`,
detail: `点击【OK】按钮后将跳过此引导步骤请根据开发需要自行下载插件、安装软件依赖。具体信息请查看日志${this.installConfig}/log/instguide.log`,
message: "安装引导器不支持当前系统。"
}).then(result => {
if (this.DeployWindow && this.DeployWindow != undefined)
@ -289,7 +646,7 @@ export class DeployMainService implements IDeployMainService {
type: "error",
title: "配置文件检查",
buttons: ["OK"],
detail: `点击【OK】按钮后将跳过此引导步骤请根据开发需要自行下载插件、安装软件依赖。具体信息请查看日志${installConfig}/log/instguide.log`,
detail: `点击【OK】按钮后将跳过此引导步骤请根据开发需要自行下载插件、安装软件依赖。具体信息请查看日志${this.installConfig}/log/instguide.log`,
message: "本地数据及网络数据校验失败"
}).then(result => {
if (this.DeployWindow && this.DeployWindow != undefined)

View File

@ -1,5 +1,5 @@
import * as os from 'os';
import * as fs from 'fs';
// import * as os from 'os';
// import * as fs from 'fs';
//获取全局变量g_index.json下载网络
export function get_g_index_url() {
@ -9,9 +9,11 @@ export function get_g_index_url() {
export function configDir() {
// 获取用户目录
const os = require('os');
const fs = require('fs');
const userHome = os.homedir();
// 创建日志目录
const configDir = `${userHome}/.config/Kylin-IDE/installconfig`;
const configDir = `${userHome}/.config/Kylin-Code/installconfig`;
if (!fs.existsSync(configDir)) {
fs.mkdirSync(configDir, { recursive: true }); // 递归创建目录
}