electron学习笔记

发布时间 2023-11-10 15:47:44作者: 启豪


1
const { app, BrowserWindow, Menu ,remote , ipcMain } = require("electron"); 2 const path = require("path"); 3 const axios = require('axios'); 4 const isMac = process.platform === 'darwin'; 5 6 const { exec ,spawnSync,spawn } = require('child_process'); 7 const fs = require('fs'); 8 const CryptoJS = require("crypto-js"); 9 const util = require('util'); 10 const net = require('net'); 11 12 const spawnPromise = util.promisify(spawn); 13 14 const filename = 'register.txt'; 15 16 function getMd5(code) { 17 let str = 'DHJKhnui2r3rfjJBNJDNK2nrj3424323ndjskad' 18 let st = 'DHJKhnui2r3rfjJBNJDNK2nrj3424323ndjskad2BNDNK' 19 const md5Hash = CryptoJS.MD5(st + code + str).toString().toUpperCase(); 20 console.log(md5Hash); 21 return md5Hash 22 } 23 24 function createFile(event,code) { 25 fs.access(filename, fs.constants.F_OK, (err) => { 26 if (err) { 27 // 计算字符串的 MD5 哈希值 28 const md5Hash = getMd5(code).toUpperCase() 29 // 文件不存在,创建文件 30 fs.writeFile(filename, md5Hash, (err) => { 31 if (err) { 32 console.error('Error creating file:', err); 33 event.sender.send('Register-error'); 34 return false 35 } else { 36 console.log('File created successfully!'); 37 event.sender.send('Register-success'); 38 return true 39 } 40 }); 41 } else { 42 console.log('File already exists'); 43 event.sender.send('Register-error'); 44 return false 45 } 46 }); 47 } 48 49 function checkFile(event ,code) { 50 fs.access(filename, fs.constants.F_OK, (err) => { 51 if (err) { 52 console.log("registerbl"); 53 event.sender.send('error'); 54 return 55 } else { 56 console.log('File already exists'); 57 // 读取文件内容 58 fs.readFile(filename, 'utf8', (err, data) => { 59 if (err) throw err; 60 const firstLine = data.split('\n')[0]; // 获取第一行字符串 61 console.log(firstLine); 62 let regCode = getMd5(code).toUpperCase() 63 if(firstLine != regCode) { 64 fs.unlink(filename, (err) => { 65 if (err) { 66 console.error('Error deleting file', err); 67 event.sender.send('error'); 68 } else { 69 console.log('File deleted successfully'); 70 event.sender.send('error'); 71 } 72 }); 73 } else { 74 event.sender.send('success'); 75 } 76 }); 77 78 return true 79 } 80 }); 81 } 82 83 function checkRegister(event,code,reg) { 84 fs.access(filename, fs.constants.F_OK, (err) => { 85 if (err) { 86 // 计算字符串的 MD5 哈希值 87 const md5Hash = getMd5(code).toUpperCase() 88 89 if(reg == md5Hash) { 90 createFile(event,code) 91 } else { 92 event.sender.send('Register-error'); 93 return false 94 } 95 } else { 96 console.log('File already exists'); 97 event.sender.send('Register-success'); 98 return true 99 } 100 }); 101 } 102 103 function createWindow() { 104 // 创建浏览器窗口 105 const mainWindow = new BrowserWindow({ 106 icon:path.join(__dirname, "/icons.ico"), 107 show: false, 108 minWidth: 1440, 109 minHeight: 900, 110 webPreferences: { 111 contextIsolation: false, 112 partition: String(+new Date()), 113 preload: path.join(__dirname, "preload.js"), 114 nodeIntegration: true, // 允许在渲染进程中使用 Node.js API 115 // contextIsolation: true, // 允许渲染进程使用主进程的变量和模块 116 webSecurity: false, // 禁用网络安全策略 117 enableRemoteModule: true 118 }, 119 }); 120 // 创建菜单模板 121 const template = [ 122 { 123 label: '文件', 124 submenu: [ 125 { 126 label: '重启软件', 127 accelerator: isMac ? 'Command+Shift+R' : 'Ctrl+Shift+R', 128 click: () => { 129 app.relaunch(); // 重新启动应用程序 130 app.quit(); 131 } 132 }, 133 { 134 label: '刷新页面', 135 accelerator: 'F5', 136 click: () => { 137 mainWindow.reload(); // 刷新主窗口 138 } 139 }, 140 { type: 'separator' }, 141 { 142 label: '退出', 143 accelerator: isMac ? 'Command+Q' : 'Ctrl+Q', 144 click: () => { 145 app.quit(); // 退出应用程序 146 } 147 } 148 ] 149 } 150 ]; 151 152 // Menu.setApplicationMenu(null); 153 // 创建菜单 154 const menu = Menu.buildFromTemplate(template); 155 // 设置应用程序菜单 156 Menu.setApplicationMenu(menu); 157 158 mainWindow.maximize(); 159 mainWindow.show(); 160 // mainWindow.webContents.openDevTools() 161 162 // 如果是开发环境就把当前运行的web端口做成客户端预览 163 // 如果是生产环境就把打包后的index做成客户端预览 164 // const startUrl = `http://localhost:8083` 165 const startUrl = `file://${path.join(__dirname, "../dist/index.html")}` 166 167 mainWindow.loadURL(startUrl); 168 // mainWindow.loadURL( 169 // NODE_ENV === "development" 170 // ? "http://localhost:8083" 171 // // : "http://localhost:8083" 172 // : `http://127.0.0.1:5501/dist` 173 // ); 174 175 // 获取cpu唯一串号 176 ipcMain.on('getCpuInfo', (event, data) => { 177 // console.log(data); // 在控制台打印收到的消息 178 // 发送回复给渲染进程 179 exec('wmic cpu get processorid /Format:List', (error, stdout, stderr) => { 180 if (error) { 181 console.error(`执行Python脚本时出错: ${error}`); 182 return; 183 } 184 // console.log(`Python脚本执行结果:\n${stdout}`); 185 let a = stdout.split("=")[1] 186 // console.log(stdout.split("=")[1].replaceAll("\r","")); 187 // console.log(a); 188 let result = a.replace(/[\n\s]/g, ''); 189 // console.log(result); 190 event.sender.send('cpuNum', getMd5(result).toUpperCase()); 191 }); 192 }); 193 194 // 复制函数 195 ipcMain.on('copy', (event, data) => { 196 // console.log(data); // 在控制台打印收到的消息 197 // 发送回复给渲染进程 198 event.sender.send('on-copy'); 199 }); 200 201 202 // 退出函数 203 ipcMain.on('quit', (event, data) => { 204 // console.log(data); // 在控制台打印收到的消息 205 // 发送回复给渲染进程 206 app.quit(); 207 }); 208 209 210 211 // 注册 212 ipcMain.on('register', (event, data,a) => { 213 console.log(data); // 在控制台打印收到的消息 214 console.log(a); // 在控制台打印收到的消息 215 // 发送回复给渲染进程 216 let flag = checkRegister(event,data,a) 217 // if(flag) { 218 // event.sender.send('Register-success'); 219 // } else{ 220 // event.sender.send('Register-error'); 221 // } 222 }); 223 224 // 检测是否注册 225 ipcMain.on('registerbl', (event, data) => { 226 console.log( "registerbl", data); // 在控制台打印收到的消息 227 // 发送回复给渲染进程 228 checkFile(event ,data) 229 }); 230 231 } 232 233 234 function isPortOpen(port) { 235 return new Promise((resolve) => { 236 const tester = net.createServer() 237 .once('error', () => resolve(false)) 238 .once('listening', () => tester.once('close', () => resolve(true)).close()) 239 .listen(port); 240 }); 241 } 242 243 244 // 这段程序将会在 Electron 结束初始化 245 // 和创建浏览器窗口的时候调用 246 // 部分 API 在 ready 事件触发后才能使用。 247 app.whenReady().then(async () => { 248 const port = 21238; 249 try { 250 const isOpen = await isPortOpen(port); 251 if (isOpen) { 252 console.log(`端口 no ${port} 未被启用`); 253 // 运行启动代码 254 // await startNode(); 255 spawnSync(process.platform === 'win32' ? 'npm.cmd' : 'npm', ['run', 'start'], { stdio: 'inherit', cwd: 'electron/front-end' }); 256 } else { 257 console.log(`端口 yes ${port} 被启用`); 258 } 259 } catch (err) { 260 console.error('发生错误:', err); 261 } 262 263 createWindow(); 264 app.on('activate', function () { 265 if (BrowserWindow.getAllWindows().length === 0) { 266 createWindow(); 267 } 268 }); 269 }); 270 271 // 除了 macOS 外,当所有窗口都被关闭的时候退出程序。 因此,通常对程序和它们在 272 // 任务栏上的图标来说,应当保持活跃状态,直到用户使用 Cmd + Q 退出。 273 app.on("window-all-closed",async function () { 274 spawnSync(process.platform === 'win32' ? 'npm.cmd' : 'npm', ['run', 'stop'], { stdio: 'inherit', cwd: 'electron/front-end' }); 275 if (process.platform !== "darwin") app.quit(); 276 });

 

 

vue中的使用

  1 <template>
  2   <div class="content">
  3     <div class="box">
  4       <div class="title">注册</div>
  5       <div class="tl">机器码:</div>
  6       <div class="line">
  7         <el-input
  8           v-model="regCode"
  9           :disabled="true"
 10           @click="showCopySuccess"
 11           class="ipt"
 12         >
 13         </el-input>
 14 
 15         <div @click="getCpuInfo" class="btn">复制</div>
 16       </div>
 17 
 18       <div class="tl">注册码:</div>
 19       
 20       <div class="line">
 21         <el-input
 22           type="textarea"
 23           placeholder="请输入内容"
 24           v-model="textarea"
 25           show-word-limit
 26           class="textareas"
 27         >
 28         </el-input>
 29       </div>
 30       <div class="tishi">
 31         联系厂家,提供机器码,以获取注册码
 32       </div>
 33       <div class="line1">
 34         <div class="btn1" @click="registers">注册</div>
 35         <div class="btn1" @click="quit">退出</div>
 36       </div>
 37     </div>
 38   </div>
 39 </template>
 40 <script>
 41 // const { ipcRenderer } = ('electron');
 42 const { ipcRenderer } = window.require('electron');
 43 export default {
 44   name: "Register",
 45   data() {
 46     return {
 47       regCode: "要复制的文本内容111",
 48       textarea:""
 49     };
 50   },
 51   created() {
 52     ipcRenderer.send('getCpuInfo')
 53     ipcRenderer.on('cpuNum', (event, arg) => {
 54       console.log(arg); // 打印收到的消息
 55       this.regCode = arg
 56       ipcRenderer.send('registerbl',arg)
 57       ipcRenderer.on('success', (event, arg) => {
 58         this.$store.commit('setRegister',true)
 59         this.$router.push('/overview')
 60       });
 61     });
 62   },
 63   mounted() {
 64     ipcRenderer.on('on-copy', (event, arg) => {
 65       console.log(arg); // 打印收到的消息
 66       this.showCopySuccess()
 67     });
 68     ipcRenderer.on('Register-success', (event, arg) => {
 69       this.$message.success('注册成功');
 70       console.log("跳转到主页");
 71       this.$router.push('/overview')
 72     });
 73     ipcRenderer.on('Register-error', (event, arg) => {
 74       this.$message.error('注册码错误');
 75     });
 76   },
 77 
 78   methods: {
 79     quit(){
 80       ipcRenderer.send('quit')
 81     },
 82     registers(){
 83       if(!this.regCode) {
 84         this.$message.error('参数错误,请联系商家');
 85         return
 86       }
 87       if(!this.textarea) {
 88         this.$message.error('注册码不能为空');
 89         return
 90       }
 91       ipcRenderer.send('register', this.regCode,this.textarea)
 92     },
 93     showCopySuccess() {
 94         const text = this.regCode
 95         const textarea = document.createElement("textarea");
 96         textarea.value = text;
 97         document.body.appendChild(textarea);
 98         textarea.select();
 99         document.execCommand("copy");
100         document.body.removeChild(textarea);
101         this.$message.success('已复制到剪贴板');
102     },
103     getCpuInfo(){
104       ipcRenderer.send('copy')
105         // this.axiosapi.ajaxGet(
106         //   '/api/getCpuInfo',
107         //   (res) => {
108         //     if (res.data.code === 200) {
109         //       console.log(res.data.data)
110         //     }
111         //   }
112         // )
113         
114     },
115   },
116 };
117 </script>
118 
119 <style lang="scss" scoped>
120 .content {
121   display: flex;
122   justify-content: center;
123   align-items: center;
124   height: 100vh;
125 }
126 .box {
127   min-width: 800px;
128   max-width: 1000px;
129   height: 40vh;
130   background-color: white;
131   padding: 20px;
132   border-radius: 10px;
133   box-shadow: -9px 15px 34px #888888;
134 }
135 
136 .tl{
137   margin-top: 30px;
138   margin-left: 55px;
139   font-size: 15px;
140 }
141 
142 .line{
143   width: 100%;
144   display: flex;
145   height: 20px;
146   // margin-top: 30px;
147   padding: 20px;
148   justify-content: center;
149 }
150 .line1{
151   width: 100%;
152   display: flex;
153   height: 100px;
154   // margin-top: 30px;
155   // padding: 20px;
156   justify-content: center;
157   align-items: center;
158 }
159 .ipt{
160   width: 80%;
161   user-select: none;
162 }
163 
164 .btn{
165   margin-left: 30px;
166   width: 55px;
167   height: 40px;
168   border-radius: 5px;
169   background-color: rgb(166, 179, 179);
170   text-align: center;
171   line-height: 40px;
172   font-size: 12px;
173   user-select: none;
174   &:hover {
175     cursor: pointer;
176   }
177 }
178 .btn1{
179   margin-left: 30px;
180   width: 150px;
181   height: 50px;
182   border-radius: 5px;
183   background-color: rgb(103, 253, 253);
184   text-align: center;
185   line-height: 50px;
186   font-size: 16px;
187   user-select: none;
188   &:hover {
189     cursor: pointer;
190   }
191 }
192 
193 
194 .title {
195   font-size: 25px;
196   font-weight: 600;
197   margin-left: 28px;
198 }
199 
200 .textareas{
201   width: 90%;
202   margin: auto;
203 }
204 
205 .tishi{
206   margin-top: 30px;
207   width: 100%;
208   text-align: center;
209   font-size: 15px;
210 }
211 
212 </style>
View Code