2023-03-23 06:56:25 +08:00

307 lines
12 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Modules to control application life and create native browser window
const { app, BrowserWindow, dialog, ipcMain, screen } = require('electron');
app.commandLine.appendSwitch("--disable-http-cache");
const path = require('path');
const fs = require('fs');
const {exec} = require('child_process');
const iconPath = path.join(__dirname, 'favicon.ico');
const task_server = require(path.join(__dirname, 'server.js'));
let config = fs.readFileSync(path.join(task_server.getDir(), `config.json`), 'utf8');
config = JSON.parse(config);
task_server.start(config.webserver_port); //start local server
let server_address = `${config.webserver_address}:${config.webserver_port}`;
const websocket_port = 8084; //目前只支持8084端口写死因为扩展里面写死了
console.log("server_address: " + server_address);
let driverPath = "";
let chromeBinaryPath = "";
let execute_path = "";
console.log(process.arch);
if (process.platform === 'win32' && process.arch === 'ia32') {
driverPath = path.join(__dirname, "chrome_win32/chromedriver_win32.exe");
chromeBinaryPath = path.join(__dirname, "chrome_win32/chrome.exe");
execute_path = path.join(__dirname, "chrome_win32/execute.bat");
} else if(process.platform === 'win32' && process.arch === 'x64') {
driverPath = path.join(__dirname, "chrome_win64/chromedriver_win64.exe");
chromeBinaryPath = path.join(__dirname, "chrome_win64/chrome.exe");
execute_path = path.join(__dirname, "chrome_win64/execute.bat");
} else if (process.platform === 'darwin') {
driverPath = path.join(__dirname, "chromedriver_mac64");
chromeBinaryPath = path.join(__dirname, "chrome_mac64.app/Contents/MacOS/Google Chrome");
execute_path = path.join(__dirname, "easyspider_executestage");
} else if (process.platform === 'linux') {
driverPath = path.join(__dirname, "chrome_linux64/chromedriver_linux64");
chromeBinaryPath = path.join(__dirname, "chrome_linux64/chrome");
execute_path = path.join(__dirname, "chrome_linux64/easyspider_executestage");
}
console.log(driverPath, chromeBinaryPath, execute_path);
let language = "en";
let driver = null;
let mainWindow = null;
let flowchart_window = null;
// var ffi = require('ffi-napi');
// var libm = ffi.Library('libm', {
// 'ceil': [ 'double', [ 'double' ] ]
// });
// libm.ceil(1.5); // 2
// const {user32FindWindowEx,
// winspoolGetDefaultPrinter,} = require('win32-api/fun');
// async function testt(){
// // 获取当前电脑当前用户默认打印机名
// const printerName = await winspoolGetDefaultPrinter()
// console.log(printerName);
// }
// testt();
function createWindow() {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 520,
height: 750,
webPreferences: {
preload: path.join(__dirname, 'src/js/preload.js')
},
icon: iconPath,
// frame: false, //取消window自带的关闭最小化等
resizable: false //禁止改变主窗口尺寸
})
// and load the index.html of the app.
// mainWindow.loadFile('src/index.html');
mainWindow.loadURL(server_address + '/index.html?user_data_folder=' + config.user_data_folder);
// 隐藏菜单栏
const { Menu } = require('electron');
Menu.setApplicationMenu(null);
mainWindow.on('close', function (e) {
if (process.platform !== 'darwin'){
app.quit();
}
});
// mainWindow.webContents.openDevTools();
// Open the DevTools.
// mainWindow.webContents.openDevTools()
}
function beginInvoke(msg) {
if (msg.type == 1) {
if (msg.message.id != -1) {
let url = "";
if (language == "zh"){
url = server_address + `/taskGrid/FlowChart_CN.html?id=${msg.message.id}&wsport=${websocket_port}&backEndAddressServiceWrapper=` + server_address;
} else if(language == "en"){
url = server_address + `/taskGrid/FlowChart.html?id=${msg.message.id}&wsport=${websocket_port}&backEndAddressServiceWrapper=` + server_address;
}
console.log(url);
flowchart_window.loadURL(url);
}
mainWindow.hide();
const window = windowManager.getActiveWindow();
// Prints the currently focused window bounds.
console.log(window.getBounds());
// This method has to be called on macOS before changing the window's bounds, otherwise it will throw an error.
// It will prompt an accessibility permission request dialog, if needed.
windowManager.requestAccessibility();
// Sets the active window's bounds.
let size = screen.getPrimaryDisplay().workAreaSize
let width = parseInt(size.width)
let height = parseInt(size.height * 0.6)
window.setBounds({ x: 0, y: size.height * 0.4, height:height, width:width });
flowchart_window.show();
} else if (msg.type == 2) {
//keyboard
const robot = require("@jitsi/robotjs");
//TODO 实现全选并删除功能,目前没有
keyInfo = msg.message.keyboardStr.split("BS}")[1];
robot.keyTap("a", "control");
robot.keyTap("backspace");
robot.typeString(keyInfo);
robot.keyTap("shift");
robot.keyTap("shift");
} else if (msg.type == 3) {
try {
if (msg.from == 0) {
socket_flowchart.send(msg.message.pipe); //直接把消息转接
}
else {
socket_window.send(msg.message.pipe);
}
} catch {
dialog.showErrorBox("Error", "Please open the flowchart window first");
}
} else if (msg.type == 5){
var child = require('child_process').execFile;
// 参数顺序: 1. task id 2. server address 3. saved_file_name 4. "remote" or "local" 5. user_data_folder
// var parameters = [msg.message.id, server_address];
let parameters = [];
console.log(msg.message)
if(msg.message.user_data_folder == null || msg.message.user_data_folder == undefined || msg.message.user_data_folder == ""){
parameters = ["--id", msg.message.id, "--server_address", server_address];
} else {
let user_data_folder_path = __dirname.indexOf("resources")>=0 && __dirname.indexOf("app")>=0? path.join(__dirname, "../../..", msg.message.user_data_folder): path.join(__dirname, msg.message.user_data_folder);
parameters = ["--id", msg.message.id, "--server_address", server_address, "--user_data_folder", user_data_folder_path];
config.user_data_folder = msg.message.user_data_folder;
fs.writeFileSync(path.join(task_server.getDir(), "config.json"), JSON.stringify(config));
}
// child('Chrome/easyspider_executestage.exe', parameters, function(err,stdout, stderr) {
// console.log(stdout);
// });
let spawn = require("child_process").spawn;
let child_process = spawn(execute_path, parameters);
child_process.stdout.on('data', function (data) {
console.log(data.toString());
});
}
}
const WebSocket = require('ws');
let socket_window = null;
let socket_start = null;
let socket_flowchart = null;
var wss = new WebSocket.Server({ port: websocket_port });
wss.on('connection', function (ws) {
ws.on('message', function (message, isBinary) {
let msg = JSON.parse(message.toString());
// console.log(msg, msg.type, msg.message);
if (msg.type == 0) {
if (msg.message.id == 0) {
socket_window = ws;
console.log("set socket_window")
}
else if (msg.message.id == 1) {
socket_start = ws;
console.log("set socket_start")
}
else if (msg.message.id == 2) {
socket_flowchart = ws;
console.log("set socket_flowchart");
}
} else {
beginInvoke(msg);
}
});
});
const { Builder, By, Key, until } = require("selenium-webdriver");
const chrome = require('selenium-webdriver/chrome');
const { ServiceBuilder } = require('selenium-webdriver/chrome');
const { rootCertificates } = require('tls');
const { exit } = require('process');
const {windowManager} = require("node-window-manager");
console.log(process.platform);
async function runBrowser(lang="en", user_data_folder='') {
const serviceBuilder = new ServiceBuilder(driverPath);
let options = new chrome.Options();
language = lang;
if(lang=="en") {
options.addExtensions(path.join(__dirname, "EasySpider_en.crx"));
} else if(lang=="zh") {
options.addExtensions(path.join(__dirname, "EasySpider_zh.crx"));
}
options.setChromeBinaryPath(chromeBinaryPath);
if(user_data_folder != ""){
let dir = __dirname.indexOf("resources")>=0 && __dirname.indexOf("app")>=0? path.join(__dirname, "../../..", user_data_folder): path.join(__dirname, user_data_folder);
options.addArguments("--user-data-dir=" + dir);
config.user_data_folder = user_data_folder;
fs.writeFileSync(path.join(task_server.getDir(), "config.json"), JSON.stringify(config));
}
driver = new Builder()
.forBrowser('chrome')
.setChromeOptions(options)
.setChromeService(serviceBuilder)
.build();
const cdpConnection = await driver.createCDPConnection("page");
let stealth_path = path.join(__dirname, "stealth.min.js");
let stealth = fs.readFileSync(stealth_path, 'utf8');
await cdpConnection.execute('Page.addScriptToEvaluateOnNewDocument', {
source: stealth,
});
try {
await driver.get(server_address + "/taskGrid/taskList.html?wsport="+websocket_port+"&backEndAddressServiceWrapper=" + server_address + "&lang=" + lang);
} finally {
// await driver.quit(); // 退出浏览器
}
}
function handleOpenBrowser(event, lang="en", user_data_folder= "") {
const webContents = event.sender;
const win = BrowserWindow.fromWebContents(webContents);
runBrowser(lang, user_data_folder);
let size = screen.getPrimaryDisplay().workAreaSize;
let width = parseInt(size.width);
let height = parseInt(size.height * 0.6);
flowchart_window = new BrowserWindow({
x:0,
y:0,
width: width,
height: height,
icon: iconPath,
});
let url = "";
let id = -1;
if (lang == "en") {
url = server_address + `/taskGrid/FlowChart.html?id=${id}&wsport=${websocket_port}&backEndAddressServiceWrapper=` + server_address;
}else if(lang == "zh") {
url = server_address + `/taskGrid/FlowChart_CN.html?id=${id}&wsport=${websocket_port}&backEndAddressServiceWrapper=` + server_address;
}
// and load the index.html of the app.
flowchart_window.loadURL(url);
flowchart_window.hide();
flowchart_window.on('close', function (event) {
mainWindow.show();
driver.quit();
});
}
function handleOpenInvoke(event, lang="en"){
const window = new BrowserWindow({icon: iconPath});
let url = "";
language = lang;
if (lang == "en") {
url = server_address + `/taskGrid/taskList.html?type=1&wsport=${websocket_port}&backEndAddressServiceWrapper=` + server_address;
}else if(lang == "zh") {
url = server_address + `/taskGrid/taskList.html?type=1&wsport=${websocket_port}&backEndAddressServiceWrapper=` + server_address + "&lang=zh";
}
// and load the index.html of the app.
window.loadURL(url);
window.maximize();
mainWindow.hide();
window.on('close', function (event) {
mainWindow.show();
});
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
ipcMain.on('start-design', handleOpenBrowser);
ipcMain.on('start-invoke', handleOpenInvoke);
createWindow();
app.on('activate', function () {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0){
createWindow();
}
})
})
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', function () {
if (process.platform !== 'darwin'){
app.quit();
}
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.