commit 7c30acc52649b9ea0bdcf2ecdb2f0118755080ca Author: qubiaobiao <3294694717@qq.com> Date: Tue Oct 31 17:24:10 2023 +0800 烧录软件(单个烧录) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cda29b0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +node_modules +.DS_Store +dist +dist-ssr +*.local + +.vscode +.idea diff --git a/README.md b/README.md new file mode 100644 index 0000000..d037731 --- /dev/null +++ b/README.md @@ -0,0 +1,26 @@ +# Vite Electron Typescript Template + +`vite 2` `vue 3` `electron 12` + +## How to use +clone the repo via git and install dependencies: +```shell +git clone --depth 1 --single-branch https://github.com/hocili/vite-electron-typescript-template.git your-project-name +cd your-project-name +yarn +``` + +## Starting Development +Start the app in the `dev` environment: +```shell +yarn dev +``` + +```shell +yarn electron:dev +``` +## Packaging for Production +To package apps for the local platform: +```shell +yarn electron:build +``` diff --git a/afterAllArtifactBuildHook.js b/afterAllArtifactBuildHook.js new file mode 100644 index 0000000..110f5b6 --- /dev/null +++ b/afterAllArtifactBuildHook.js @@ -0,0 +1,57 @@ +const fs = require('fs') +const archiver = require('archiver') +const { Platform } = require("electron-builder") +const { name } = require('./package.json') + +exports.default = function (buildResult) { + // you can return additional files to publish + // return ["/path/to/additional/result/file"] + + const zipFilePath = buildResult.outDir + '/' + name + '.zip' + const sourceDirPath = buildResult.outDir + '/' + Platform.current().buildConfigurationKey + '-unpacked/' + + // create a file to stream archive data to. + const output = fs.createWriteStream(zipFilePath) + const archive = archiver('zip', { + zlib: { level: 9 } // Sets the compression level. + }) + + // listen for all archive data to be written + // 'close' event is fired only when a file descriptor is involved + output.on('close', function() { + console.log(archive.pointer() + ' total bytes'); + console.log('archiver has been finalized and the output file descriptor has closed.'); + }); + + // This event is fired when the data source is drained no matter what was the data source. + // It is not part of this library but rather from the NodeJS Stream API. + // @see: https://nodejs.org/api/stream.html#stream_event_end + output.on('end', function() { + console.log('Data has been drained'); + }); + + // good practice to catch warnings (ie stat failures and other non-blocking errors) + archive.on('warning', function(err) { + if (err.code === 'ENOENT') { + // log warning + } else { + // throw error + throw err; + } + }); + + // good practice to catch this error explicitly + archive.on('error', function(err) { + throw err; + }); + + // pipe archive data to the file + archive.pipe(output); + + // append files from a sub-directory, putting its contents at the root of archive + archive.directory(sourceDirPath, false); + + // finalize the archive (ie we are done appending files but streams have to finish yet) + // 'close', 'end' or 'finish' may be fired right after calling this method so register to them beforehand + archive.finalize(); +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..b81ce4f --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + + esp32程序烧录 + + +
+ + + diff --git a/index.js b/index.js new file mode 100644 index 0000000..b729629 --- /dev/null +++ b/index.js @@ -0,0 +1,4 @@ +require('ts-node').register({ + project:'./tsconfig.electron.json' +}); +require('./src/main/app.ts') \ No newline at end of file diff --git a/npminstall-debug.log b/npminstall-debug.log new file mode 100644 index 0000000..668fbbd --- /dev/null +++ b/npminstall-debug.log @@ -0,0 +1,210 @@ +{ + root: 'D:\\VS Code\\hwasmart-yanfaleixiangmu-esp32-program-burner-', + registry: 'https://registry.npmmirror.com', + pkgs: [ + { + name: 'archiver', + version: '5.3.1', + type: 'version', + alias: undefined, + arg: [Result] + }, + { + name: 'dev', + version: 'latest', + type: 'tag', + alias: undefined, + arg: [Result] + } + ], + production: false, + cacheStrict: false, + cacheDir: 'C:\\Users\\OEM\\.npminstall_tarball', + env: { + npm_config_registry: 'https://registry.npmmirror.com', + npm_config_argv: '{"remain":[],"cooked":["--fix-bug-versions","--china","--userconfig=C:\\\\Users\\\\OEM\\\\.cnpmrc","--disturl=https://cdn.npmmirror.com/binaries/node","--registry=https://registry.npmmirror.com","archiver@5.3.1","dev"],"original":["--fix-bug-versions","--china","--userconfig=C:\\\\Users\\\\OEM\\\\.cnpmrc","--disturl=https://cdn.npmmirror.com/binaries/node","--registry=https://registry.npmmirror.com","archiver@5.3.1","dev"]}', + npm_config_user_agent: 'npminstall/7.9.0 npm/? node/v16.18.1 win32 x64', + npm_config_cache: 'C:\\Users\\OEM\\.npminstall_tarball', + NODE: 'C:\\Program Files\\nodejs\\node.exe', + npm_node_execpath: 'C:\\Program Files\\nodejs\\node.exe', + npm_execpath: 'C:\\Users\\OEM\\AppData\\Roaming\\npm\\node_modules\\cnpm\\node_modules\\npminstall\\bin\\install.js', + npm_config_userconfig: 'C:\\Users\\OEM\\.cnpmrc', + npm_config_disturl: 'https://cdn.npmmirror.com/binaries/node', + npm_config_r: 'https://registry.npmmirror.com', + COREPACK_NPM_REGISTRY: 'https://registry.npmmirror.com', + NODEJS_ORG_MIRROR: 'https://cdn.npmmirror.com/binaries/node', + NVM_NODEJS_ORG_MIRROR: 'https://cdn.npmmirror.com/binaries/node', + PHANTOMJS_CDNURL: 'https://cdn.npmmirror.com/binaries/phantomjs', + CHROMEDRIVER_CDNURL: 'https://cdn.npmmirror.com/binaries/chromedriver', + OPERADRIVER_CDNURL: 'https://cdn.npmmirror.com/binaries/operadriver', + CYPRESS_DOWNLOAD_PATH_TEMPLATE: 'https://cdn.npmmirror.com/binaries/cypress/${version}/${platform}-${arch}/cypress.zip', + ELECTRON_MIRROR: 'https://cdn.npmmirror.com/binaries/electron/', + ELECTRON_BUILDER_BINARIES_MIRROR: 'https://cdn.npmmirror.com/binaries/electron-builder-binaries/', + SASS_BINARY_SITE: 'https://cdn.npmmirror.com/binaries/node-sass', + SWC_BINARY_SITE: 'https://cdn.npmmirror.com/binaries/node-swc', + NWJS_URLBASE: 'https://cdn.npmmirror.com/binaries/nwjs/v', + PUPPETEER_DOWNLOAD_HOST: 'https://cdn.npmmirror.com/binaries/chrome-for-testing', + PUPPETEER_DOWNLOAD_BASE_URL: 'https://cdn.npmmirror.com/binaries/chrome-for-testing', + PLAYWRIGHT_DOWNLOAD_HOST: 'https://cdn.npmmirror.com/binaries/playwright', + SENTRYCLI_CDNURL: 'https://cdn.npmmirror.com/binaries/sentry-cli', + SAUCECTL_INSTALL_BINARY_MIRROR: 'https://cdn.npmmirror.com/binaries/saucectl', + RE2_DOWNLOAD_MIRROR: 'https://cdn.npmmirror.com/binaries/node-re2', + RE2_DOWNLOAD_SKIP_PATH: 'true', + PRISMA_ENGINES_MIRROR: 'https://cdn.npmmirror.com/binaries/prisma', + npm_config_better_sqlite3_binary_host: 'https://cdn.npmmirror.com/binaries/better-sqlite3', + npm_config_keytar_binary_host: 'https://cdn.npmmirror.com/binaries/keytar', + npm_config_sharp_binary_host: 'https://cdn.npmmirror.com/binaries/sharp', + npm_config_sharp_libvips_binary_host: 'https://cdn.npmmirror.com/binaries/sharp-libvips', + npm_config_robotjs_binary_host: 'https://cdn.npmmirror.com/binaries/robotjs', + npm_rootpath: 'D:\\VS Code\\hwasmart-yanfaleixiangmu-esp32-program-burner-', + INIT_CWD: 'D:\\VS Code\\hwasmart-yanfaleixiangmu-esp32-program-burner-' + }, + binaryMirrors: { + ENVS: { + COREPACK_NPM_REGISTRY: 'https://registry.npmmirror.com', + NODEJS_ORG_MIRROR: 'https://cdn.npmmirror.com/binaries/node', + NVM_NODEJS_ORG_MIRROR: 'https://cdn.npmmirror.com/binaries/node', + PHANTOMJS_CDNURL: 'https://cdn.npmmirror.com/binaries/phantomjs', + CHROMEDRIVER_CDNURL: 'https://cdn.npmmirror.com/binaries/chromedriver', + OPERADRIVER_CDNURL: 'https://cdn.npmmirror.com/binaries/operadriver', + CYPRESS_DOWNLOAD_PATH_TEMPLATE: 'https://cdn.npmmirror.com/binaries/cypress/${version}/${platform}-${arch}/cypress.zip', + ELECTRON_MIRROR: 'https://cdn.npmmirror.com/binaries/electron/', + ELECTRON_BUILDER_BINARIES_MIRROR: 'https://cdn.npmmirror.com/binaries/electron-builder-binaries/', + SASS_BINARY_SITE: 'https://cdn.npmmirror.com/binaries/node-sass', + SWC_BINARY_SITE: 'https://cdn.npmmirror.com/binaries/node-swc', + NWJS_URLBASE: 'https://cdn.npmmirror.com/binaries/nwjs/v', + PUPPETEER_DOWNLOAD_HOST: 'https://cdn.npmmirror.com/binaries/chrome-for-testing', + PUPPETEER_DOWNLOAD_BASE_URL: 'https://cdn.npmmirror.com/binaries/chrome-for-testing', + PLAYWRIGHT_DOWNLOAD_HOST: 'https://cdn.npmmirror.com/binaries/playwright', + SENTRYCLI_CDNURL: 'https://cdn.npmmirror.com/binaries/sentry-cli', + SAUCECTL_INSTALL_BINARY_MIRROR: 'https://cdn.npmmirror.com/binaries/saucectl', + RE2_DOWNLOAD_MIRROR: 'https://cdn.npmmirror.com/binaries/node-re2', + RE2_DOWNLOAD_SKIP_PATH: 'true', + PRISMA_ENGINES_MIRROR: 'https://cdn.npmmirror.com/binaries/prisma', + npm_config_better_sqlite3_binary_host: 'https://cdn.npmmirror.com/binaries/better-sqlite3', + npm_config_keytar_binary_host: 'https://cdn.npmmirror.com/binaries/keytar', + npm_config_sharp_binary_host: 'https://cdn.npmmirror.com/binaries/sharp', + npm_config_sharp_libvips_binary_host: 'https://cdn.npmmirror.com/binaries/sharp-libvips', + npm_config_robotjs_binary_host: 'https://cdn.npmmirror.com/binaries/robotjs' + }, + '@ali/s2': { host: 'https://cdn.npmmirror.com/binaries/looksgood-s2' }, + sharp: { replaceHostFiles: [Array], replaceHostMap: [Object] }, + '@tensorflow/tfjs-node': { + replaceHostFiles: [Array], + replaceHostRegExpMap: [Object], + replaceHostMap: [Object] + }, + cypress: { + host: 'https://cdn.npmmirror.com/binaries/cypress', + newPlatforms: [Object] + }, + 'utf-8-validate': { + host: 'https://cdn.npmmirror.com/binaries/utf-8-validate/v{version}' + }, + xprofiler: { + remote_path: './xprofiler/v{version}/', + host: 'https://cdn.npmmirror.com/binaries' + }, + leveldown: { host: 'https://cdn.npmmirror.com/binaries/leveldown/v{version}' }, + couchbase: { host: 'https://cdn.npmmirror.com/binaries/couchbase/v{version}' }, + gl: { host: 'https://cdn.npmmirror.com/binaries/gl/v{version}' }, + sqlite3: { + host: 'https://cdn.npmmirror.com/binaries/sqlite3', + remote_path: 'v{version}' + }, + '@journeyapps/sqlcipher': { host: 'https://cdn.npmmirror.com/binaries' }, + grpc: { + host: 'https://cdn.npmmirror.com/binaries', + remote_path: '{name}/v{version}' + }, + 'grpc-tools': { host: 'https://cdn.npmmirror.com/binaries' }, + wrtc: { + host: 'https://cdn.npmmirror.com/binaries', + remote_path: '{name}/v{version}' + }, + fsevents: { host: 'https://cdn.npmmirror.com/binaries/fsevents' }, + nodejieba: { host: 'https://cdn.npmmirror.com/binaries/nodejieba' }, + canvas: { host: 'https://cdn.npmmirror.com/binaries/canvas' }, + 'skia-canvas': { host: 'https://cdn.npmmirror.com/binaries/skia-canvas' }, + 'flow-bin': { + replaceHost: 'https://github.com/facebook/flow/releases/download/v', + host: 'https://cdn.npmmirror.com/binaries/flow/v' + }, + 'jpegtran-bin': { + replaceHost: [Array], + host: 'https://cdn.npmmirror.com/binaries/jpegtran-bin' + }, + 'cwebp-bin': { + replaceHost: [Array], + host: 'https://cdn.npmmirror.com/binaries/cwebp-bin' + }, + 'zopflipng-bin': { + replaceHost: [Array], + host: 'https://cdn.npmmirror.com/binaries/zopflipng-bin' + }, + 'optipng-bin': { + replaceHost: [Array], + host: 'https://cdn.npmmirror.com/binaries/optipng-bin' + }, + mozjpeg: { + replaceHost: [Array], + host: 'https://cdn.npmmirror.com/binaries/mozjpeg-bin' + }, + gifsicle: { + replaceHost: [Array], + host: 'https://cdn.npmmirror.com/binaries/gifsicle-bin' + }, + 'pngquant-bin': { + replaceHost: [Array], + host: 'https://cdn.npmmirror.com/binaries/pngquant-bin', + replaceHostMap: [Object] + }, + 'pngcrush-bin': { + replaceHost: [Array], + host: 'https://cdn.npmmirror.com/binaries/pngcrush-bin' + }, + 'jpeg-recompress-bin': { + replaceHost: [Array], + host: 'https://cdn.npmmirror.com/binaries/jpeg-recompress-bin' + }, + 'advpng-bin': { + replaceHost: [Array], + host: 'https://cdn.npmmirror.com/binaries/advpng-bin' + }, + 'pngout-bin': { + replaceHost: [Array], + host: 'https://cdn.npmmirror.com/binaries/pngout-bin' + }, + 'jpegoptim-bin': { + replaceHost: [Array], + host: 'https://cdn.npmmirror.com/binaries/jpegoptim-bin' + }, + argon2: { host: 'https://cdn.npmmirror.com/binaries/argon2' }, + 'ali-zeromq': { host: 'https://cdn.npmmirror.com/binaries/ali-zeromq' }, + 'ali-usb_ctl': { host: 'https://cdn.npmmirror.com/binaries/ali-usb_ctl' }, + 'gdal-async': { host: 'https://cdn.npmmirror.com/binaries/node-gdal-async' }, + 'libpg-query': { host: 'https://cdn.npmmirror.com/binaries' } + }, + forbiddenLicenses: null, + flatten: false, + proxy: undefined, + prune: false, + disableFallbackStore: false, + workspacesMap: Map(0) {}, + enableWorkspace: false, + workspaceRoot: 'D:\\VS Code\\hwasmart-yanfaleixiangmu-esp32-program-burner-', + isWorkspaceRoot: true, + isWorkspacePackage: false, + offline: false, + strictSSL: true, + ignoreScripts: false, + foregroundScripts: false, + ignoreOptionalDependencies: false, + detail: false, + forceLinkLatest: false, + trace: false, + engineStrict: false, + registryOnly: false, + client: false, + autoFixVersion: [Function: autoFixVersion] +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..2fe8d2f --- /dev/null +++ b/package.json @@ -0,0 +1,54 @@ +{ + "name": "esp32-program-batch-burner", + "version": "3.3.3", + "description": "esp32程序批量烧录", + "main": "dist/main/app.js", + "scripts": { + "dev": "vite", + "build": "vite build", + "serve": "vite preview", + "electron:dev": "cross-env NODE_ENV=development electron index.js", + "electron:copy-esp32-dir": "fse copy ./public/esp32/ ./dist/release/win-unpacked/esp32/", + "electron:build": "rimraf dist && vite build && tsc -p tsconfig.electron.json && electron-builder --dir && yarn electron:copy-esp32-dir" + }, + "dependencies": { + "archiver": "5.3.1", + "serialport": "9.2.4", + "vue": "^3.2.26" + }, + "devDependencies": { + "@atao60/fse-cli": "^0.1.7", + "@vitejs/plugin-vue": "^1.1.5", + "@vue/compiler-sfc": "^3.2.26", + "archiver": "^5.3.1", + "autoprefixer": "^10.4.2", + "cross-env": "^7.0.3", + "electron": "13.6.6", + "electron-builder": "^22.10.5", + "electron-rebuild": "2.3.5", + "postcss": "^8.4.5", + "rimraf": "^3.0.2", + "tailwindcss": "^3.0.13", + "ts-node": "^9.1.1", + "typescript": "^4.2.3", + "vite": "^2.0.5" + }, + "build": { + "productName": "esp32程序批量烧录", + "appId": "your.id", + "mac": { + "category": "your.app.category.type" + }, + "files": [ + "dist/main/**/*", + "dist/render/**/*" + ], + "win": { + "icon": "./public/favicon.ico" + }, + "directories": { + "output": "dist/release" + }, + "afterAllArtifactBuild": "afterAllArtifactBuildHook.js" + } +} diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..33ad091 --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/public/esp32/boot_app0.bin b/public/esp32/boot_app0.bin new file mode 100644 index 0000000..13562ca Binary files /dev/null and b/public/esp32/boot_app0.bin differ diff --git a/public/esp32/bootloader.bin b/public/esp32/bootloader.bin new file mode 100644 index 0000000..186c11d Binary files /dev/null and b/public/esp32/bootloader.bin differ diff --git a/public/esp32/esptool.exe b/public/esp32/esptool.exe new file mode 100644 index 0000000..b8d92d7 Binary files /dev/null and b/public/esp32/esptool.exe differ diff --git a/public/esp32/partitions.bin b/public/esp32/partitions.bin new file mode 100644 index 0000000..741c057 Binary files /dev/null and b/public/esp32/partitions.bin differ diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..1b51f8f Binary files /dev/null and b/public/favicon.ico differ diff --git a/src/main/app.ts b/src/main/app.ts new file mode 100644 index 0000000..6691a50 --- /dev/null +++ b/src/main/app.ts @@ -0,0 +1,58 @@ +import { app, Menu, BrowserWindow } from 'electron' +import { join } from "path" +import './fileManager' +import './burnManager' +import serialPortManager from './serialPortManager' + +Menu.setApplicationMenu(null) + +function createWindow() { + const win = new BrowserWindow({ + width: 800, + height: 600, + minWidth: 560, + minHeight: 400, + title:'esp32程序烧录', + icon: join(__dirname, '../../public/favicon.ico'), + webPreferences: { + nodeIntegration: true, + preload: join(__dirname, 'preload.js') + } + }) + + if (process.env.NODE_ENV === 'development') { + win.loadURL('http://localhost:3000/') + win.webContents.openDevTools() + } else { + win.loadFile('dist/render/index.html') + } + + win.webContents.on('did-finish-load', () => { + serialPortManager.sendPortList(win.webContents) + }); + + win.hookWindowMessage(537, (wParam, lParam) => { + // WM_DEVICECHANGE = 537; 通知应用程序对设备或计算机的硬件配置的更改 + // console.log('WM_DEVICECHANGE'); + if ((wParam[0] == 0 && wParam[1] == 0x80) || (wParam[0] == 0x04 && wParam[1] == 0x80)) { + // DBT_DEVICEREMOVECOMPLETE 0x8004 已删除设备或介质 + // DBT_DEVICEARRIVAL 0x8000 已插入设备或介质,现已推出 + // console.log(wParam) + serialPortManager.sendPortList(win.webContents) + } + }); +} + +app.whenReady().then(createWindow) + +app.on('window-all-closed', () => { + if (process.platform !== 'darwin') { + app.quit() + } +}) + +app.on('activate', () => { + if (BrowserWindow.getAllWindows().length === 0) { + createWindow() + } +}) \ No newline at end of file diff --git a/src/main/burnManager.js b/src/main/burnManager.js new file mode 100644 index 0000000..0f0959b --- /dev/null +++ b/src/main/burnManager.js @@ -0,0 +1,85 @@ +import { ipcMain } from 'electron' +import { execFile } from 'child_process' + +const ESP32_RELATIVE_PATH = process.env.NODE_ENV === 'development' ? './public/esp32/' : './esp32/' + +ipcMain.on('BURN', (event, {selectedPort, selectedFilePath, errsum, sucsum}) => { + // event.reply('CLEAN_MSG') + execFile(ESP32_RELATIVE_PATH + 'esptool.exe', + ['--chip', 'esp32', '--port', selectedPort, '--baud', '921600', '--before', 'default_reset', '--after', 'hard_reset', 'write_flash', '-z', '--flash_mode', 'dio', '--flash_freq', '80m', '--flash_size', 'detect', + '0xe000', ESP32_RELATIVE_PATH + 'boot_app0.bin', + '0x1000', ESP32_RELATIVE_PATH + 'bootloader.bin', + '0x10000', selectedFilePath, + '0x8000', ESP32_RELATIVE_PATH + 'partitions.bin'], (error, stdout, stderr) => { + if (error) { + console.log('-----------------------------') + console.error(error); + console.log('-----------------------------') + let errmsg + let errget = /A fatal error occurred/ + let porterr = /Failed to open port/ + let pererr = /Permission denied/ + let wrong = /SerialException: Cannot configure port, something went wrong. Original message: OSError/ + if(errget.test(stdout)){ + console.log('错误') + let timeout = /Timed out waiting for packet header/ + let nodata = /No serial data received/ + let noise = /Possible serial noise or corruption/ + let flash = /Failed to write compressed data to flash/ + let md5err = /MD5 of file does not match data in flash/ + let chiperr = /This chip is ESP32-S2 not ESP32. Wrong --chip argument/ + if(timeout.test(stdout)){ + console.log('esp32模组未正常进入下载模式或串口被占用') + errmsg = '请检查串口调试助手工具查看是否有进入下载模式的打印或关闭串口后重新烧录' + }else if(nodata.test(stdout)){ + console.log('TX、RX引脚未连接或usb转串口工具硬件存在问题') + errmsg = '请检查串口引脚连接是否正常或更换usb转串口工具后重新烧录' + }else if(noise.test(stdout)){ + console.log('usb电缆错误或开发板spi flash 引脚短路或电压不稳定') + errmsg = '请尝试更换usb电缆、更换模组、更换开发板或更换稳压电源后重新烧录' + }else if(flash.test(stdout)){ + console.log('flah参数问题') + errmsg = '请确保电源稳定、以及串口连接无异常,重试下载烧录程序后重新烧录' + }else if(md5err.test(stdout)){ + console.log('flash损坏或引脚焊接问题') + errmsg = 'MD5文件与flash中的数据不匹配,请重试烧录' + }else if(chiperr.test(stdout)){ + console.log('串口连接的设备不是烧录设备') + errmsg = '请确认串口连接的是烧录设备后重新烧录' + } + }else if(porterr.test(stdout)){ + console.log('没有串口权限') + errmsg = '请提升用户权限后重新烧录' + }else if(pererr.test(stdout)){ + console.log('串口被占用') + errmsg = '请检查串口调试助手工具关闭串口后重新烧录' + }else if(wrong.test(error)){ + console.log('无法配置串口') + errmsg = '请确保烧录设备已正确连接到计算机并检查串口配置后重新烧录' + }else{ + console.log('未知错误') + errmsg = '未知错误,请重新烧录' + } + // event.reply('ALERT_MSG', errmsg) + event.reply('ERR_SUM', errsum+1) + // event.reply('APPEND_MSG', error.stack) + console.log('-----------------------------') + console.log(stdout); + console.log('-----------------------------') + // event.reply('APPEND_MSG', stdout) + event.reply('APPEND_MSG', selectedPort + '烧录失败' + '\n' + error.stack + stdout) + event.reply('FAILED_RESULT', selectedPort) + event.reply('BURN_END') + }else{ + console.log('-----------------------------') + console.log(stdout); + console.log('-----------------------------') + // event.reply('ALERT_MSG', '烧录成功!') + event.reply('SUC_SUM', sucsum+1) + // event.reply('APPEND_MSG', stdout) + event.reply('APPEND_MSG', selectedPort + '烧录成功') + event.reply('SUC_RESULT', selectedPort) + event.reply('BURN_END') + } + }); +}) \ No newline at end of file diff --git a/src/main/data.js b/src/main/data.js new file mode 100644 index 0000000..a840ffe --- /dev/null +++ b/src/main/data.js @@ -0,0 +1,6 @@ +export const filters = [ + { usbProductId: 8963 , usbVendorId: 1659 }, // 核心处理模块(micro-usb),蓝色无线通信模块 + { usbProductId: 29986, usbVendorId: 6790 }, // 核心处理模块(type-c),红色无线通信模块 + { usbProductId: 29987, usbVendorId: 6790 }, // 核心处理模块(type-c) + ] + \ No newline at end of file diff --git a/src/main/fileManager.js b/src/main/fileManager.js new file mode 100644 index 0000000..2c094e2 --- /dev/null +++ b/src/main/fileManager.js @@ -0,0 +1,14 @@ +import { dialog, ipcMain } from 'electron' + +ipcMain.on('SELECT_FILE', (event) => { + const filePaths = dialog.showOpenDialogSync({ + filters: [{name: 'esp32 bin file', extensions: ['bin']}], + properties: ['openFile'] + }) + + if (filePaths === undefined) { + return + } + + event.reply('SELECT_FILE', filePaths[0]) +}) \ No newline at end of file diff --git a/src/main/preload.js b/src/main/preload.js new file mode 100644 index 0000000..3e8408d --- /dev/null +++ b/src/main/preload.js @@ -0,0 +1,20 @@ +const {ipcRenderer, contextBridge} = require('electron') + +contextBridge.exposeInMainWorld('ipcRenderer', { + send: (channel, data) => { + // whitelist channels + let validChannels = ['toMain'] + if (validChannels.includes(channel)) { + ipcRenderer.send(channel, data) + } + ipcRenderer.send(channel, data) + }, + receive: (channel, func) => { + let validChannels = ['fromMain'] + if (validChannels.includes(channel)) { + // Deliberately strip event as it includes `sender` + ipcRenderer.on(channel, (event, ...args) => func(...args)) + } + ipcRenderer.on(channel, (event, ...args) => func(...args)) + } +}) \ No newline at end of file diff --git a/src/main/serialPortManager.js b/src/main/serialPortManager.js new file mode 100644 index 0000000..af90ac3 --- /dev/null +++ b/src/main/serialPortManager.js @@ -0,0 +1,25 @@ +import SerialPort from 'serialport' +import { filters } from './data' + +const serialPortManager = { + sendPortList: async (sender) => { + if (!sender) return + const ports = await serialPortManager.list_ports() + let targetArr = [] + ports.forEach(element => { + filters.forEach(item => { + //十六进制转十进制 + if(parseInt(element.vendorId,16)==item.usbVendorId&&parseInt(element.productId,16)==item.usbProductId){ + targetArr.push(element) + } + }) + }) + sender.send('LIST_PORTS', targetArr) + }, + list_ports: async () => { + const ports = await SerialPort.list() + return ports + } +} + +export default serialPortManager \ No newline at end of file diff --git a/src/render/App.vue b/src/render/App.vue new file mode 100644 index 0000000..5855cad --- /dev/null +++ b/src/render/App.vue @@ -0,0 +1,12 @@ + + + diff --git a/src/render/assets/logo.png b/src/render/assets/logo.png new file mode 100644 index 0000000..f3d2503 Binary files /dev/null and b/src/render/assets/logo.png differ diff --git a/src/render/components/ProgramBurnForm.vue b/src/render/components/ProgramBurnForm.vue new file mode 100644 index 0000000..69abcdc --- /dev/null +++ b/src/render/components/ProgramBurnForm.vue @@ -0,0 +1,444 @@ +