|
@@ -0,0 +1,212 @@
|
|
|
+'use strict'
|
|
|
+
|
|
|
+/**
|
|
|
+ * 读取注册表获取纵横软件
|
|
|
+ *
|
|
|
+ * @author EllisRan.
|
|
|
+ * @date 2018/6/20
|
|
|
+ * @version
|
|
|
+ */
|
|
|
+import db from '../../database/index'
|
|
|
+const fs = require('fs')
|
|
|
+const fse = require('fs-extra')
|
|
|
+const path = require('path')
|
|
|
+const ffi = require('ffi')
|
|
|
+const electron = require('electron')
|
|
|
+const ipcMain = electron.ipcMain
|
|
|
+const regeditPath64 = 'HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'
|
|
|
+const regeditPath32 = 'HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall'
|
|
|
+const regeditPath = isOSWin64() ? regeditPath64 : regeditPath32
|
|
|
+const regedit = require('regedit')
|
|
|
+let globalNUM = 0
|
|
|
+
|
|
|
+const updateInstall = function (win) {
|
|
|
+ ipcMain.on('updateInstall', function () {
|
|
|
+ regedit.list(regeditPath).on('data', async function (result) {
|
|
|
+ try {
|
|
|
+ // let flag = false
|
|
|
+ // 每次自动获取更新软件内容先让数据库isshow都为false,然后再执行getExeDataList方法里把isshow包含的变true,
|
|
|
+ // 最后再检测把还是false的删除,完成已删除软件功能(手动添加的exe信息除外)
|
|
|
+ await productAndExeDataIsshow()
|
|
|
+ let softwarelist = result.data.keys
|
|
|
+ let promiseArr = []
|
|
|
+ for (let i in softwarelist) {
|
|
|
+ if (softwarelist[i].indexOf('SmartCost_') !== -1) {
|
|
|
+ promiseArr.push(getExeDataList(softwarelist[i]))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ await Promise.all(promiseArr)
|
|
|
+ .then(async function (result) {
|
|
|
+ let delnum = await delProductAndExeDataAsync()
|
|
|
+ await db.read().set('sc_hadInstall.first', false).write()
|
|
|
+ let exeInfo = await db.read().get('sc_exeData').last().value()
|
|
|
+ let gourl = exeInfo.pid === undefined ? 1 : exeInfo.pid
|
|
|
+ await db.read().set('sc_hadInstall.url', '/softwarestartup/' + gourl).write()
|
|
|
+ if (promiseArr !== undefined && promiseArr.length !== 0) {
|
|
|
+ win.webContents.send('successUpdate', { id: gourl, num: globalNUM, delnum: delnum })
|
|
|
+ globalNUM = 0
|
|
|
+ } else {
|
|
|
+ win.webContents.send('failedUpdate', { id: '1' })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch(function () {
|
|
|
+ win.webContents.send('failedUpdate', { id: '1' })
|
|
|
+ })
|
|
|
+ } catch (err) {
|
|
|
+ console.log(err)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ /**
|
|
|
+ * make all data isshow: true=>false
|
|
|
+ */
|
|
|
+ async function productAndExeDataIsshow () {
|
|
|
+ await db.read().get('sc_productData').updateWhere({ isshow: true }, { isshow: false }).write()
|
|
|
+ await db.read().get('sc_exeData').updateWhere({ auto: true, isshow: true }, { isshow: false }).write()
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * delete data by isshow=false
|
|
|
+ * @return {int}
|
|
|
+ */
|
|
|
+ async function delProductAndExeDataAsync () {
|
|
|
+ // 这里必须静止1s等Promise.all里的getExeDataList方法所有获取执行完才可以获取正确的num,原因不明......
|
|
|
+ await sleep(1000)
|
|
|
+ let num = await db.read().get('sc_exeData').filter({ auto: true, isshow: false }).size().value()
|
|
|
+ // 先让默认的“未分类” isshow:true,免于被删除,当不存在手动添加的软件或自动检测软件的时候,暂时隐藏“未分类”,
|
|
|
+ // 当启动器不存在任何软件时,默认显示“未分类”
|
|
|
+ let manualnum = db.read().get('sc_exeData').filter({ auto: false }).size().value()
|
|
|
+ let flag = db.read().get('sc_productData').getById('1').value().isshow
|
|
|
+ if (!flag) {
|
|
|
+ db.read().get('sc_productData').updateById('1', { isshow: true }).write()
|
|
|
+ }
|
|
|
+ db.read().get('sc_productData').removeWhere({ isshow: false }).write()
|
|
|
+ let allnum = db.read().get('sc_exeData').size().value()
|
|
|
+ if (manualnum === 0 && !flag && allnum !== 0) {
|
|
|
+ db.read().get('sc_productData').updateById('1', { isshow: false }).write()
|
|
|
+ }
|
|
|
+ db.read().get('sc_exeData').removeWhere({ auto: true, isshow: false }).write()
|
|
|
+ return num
|
|
|
+ }
|
|
|
+
|
|
|
+ const sleep = (timeout = 2000) => new Promise(resolve => {
|
|
|
+ setTimeout(resolve, timeout)
|
|
|
+ })
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断文件名是否包含纵横软件exe的部分名称
|
|
|
+ * @param item
|
|
|
+ * @return {boolean}
|
|
|
+ */
|
|
|
+ function existSoftwareName (item) {
|
|
|
+ // 纵横软件exe所带包含的文件名
|
|
|
+ const smartcostSoftwareHeader = ['SmartCost', 'Measure', 'DrawingBuilder', 'BillsEditor']
|
|
|
+ let flag = false
|
|
|
+ for (let i = 0; i < smartcostSoftwareHeader.length; i++) {
|
|
|
+ if (item.indexOf(smartcostSoftwareHeader[i]) !== -1) {
|
|
|
+ flag = true
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return flag
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * node 循环和异步解决方案
|
|
|
+ * @param Info
|
|
|
+ */
|
|
|
+ function getExeDataList (Info) {
|
|
|
+ return new Promise(resolve => {
|
|
|
+ // setTimeout(function () {
|
|
|
+ regedit.list(regeditPath + '\\' + Info).on('data', async function (result) {
|
|
|
+ let values = result.data.values
|
|
|
+ let simpleVersion = values['DisplayVersion'] === undefined || values['DisplayVersion'] === null ? '' : values['DisplayVersion'].value.split('_')
|
|
|
+ let exeData = {
|
|
|
+ path: values['Inno Setup: App Path'].value,
|
|
|
+ name: values['DisplayName'].value,
|
|
|
+ regeditName: Info,
|
|
|
+ fileName: values['Inno Setup: Icon Group'].value,
|
|
|
+ simpleName: simpleVersion === '' ? '' : simpleVersion[0],
|
|
|
+ versionName: simpleVersion === '' ? '' : simpleVersion[1]
|
|
|
+ }
|
|
|
+ let dirname = await fs.readdirSync(exeData.path)
|
|
|
+ dirname.forEach(async function (item, index) {
|
|
|
+ if (path.extname(item) === '.exe' && existSoftwareName(item)) {
|
|
|
+ let pathstr = path.join('data/fileInfo.dll')
|
|
|
+ let libm = ffi.Library(pathstr, {
|
|
|
+ 'GetFileInfo': ['string', ['string']]
|
|
|
+ })
|
|
|
+ let fileinfo = JSON.parse(await libm.GetFileInfo(path.join(exeData.path, item)))
|
|
|
+ exeData.fileVersion = fileinfo.FileVersion
|
|
|
+ exeData.productName = fileinfo.ProductName
|
|
|
+ exeData.productVersion = fileinfo.ProductVersion
|
|
|
+ exeData.exeName = item
|
|
|
+ let dbExeData = await db.read().get('sc_exeData').find({ exeName: exeData.exeName, path: exeData.path, fileVersion: exeData.fileVersion }).value()
|
|
|
+ if (dbExeData === undefined || dbExeData === null) {
|
|
|
+ // 先判断是否存在该产品数据库(同时关联到sc_sofeware.json文件数据),再加入安装包数据库
|
|
|
+ if (exeData.simpleName !== '') {
|
|
|
+ let softwarejson = path.join('data/sc_software.json')
|
|
|
+ let productInfo = await db.read().get('sc_productData').find({ title: exeData.simpleName }).value()
|
|
|
+ if (productInfo === undefined || productInfo === null) {
|
|
|
+ let productlist = await fse.readJsonSync(softwarejson).sc_product
|
|
|
+ for (let i in productlist) {
|
|
|
+ if (productlist[i].title === exeData.simpleName) {
|
|
|
+ let productInfo2 = {
|
|
|
+ readid: productlist[i].product_id,
|
|
|
+ title: productlist[i].title,
|
|
|
+ productName: productlist[i].productName,
|
|
|
+ src: productlist[i].src,
|
|
|
+ addtime: Date.parse(new Date()) / 1000,
|
|
|
+ isshow: true
|
|
|
+ }
|
|
|
+ let insertproudct = await db.read().get('sc_productData').insert(productInfo2).write()
|
|
|
+ exeData.pid = insertproudct.id
|
|
|
+ productInfo = insertproudct
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ exeData.pid = productInfo.id
|
|
|
+ await db.read().get('sc_productData').updateById(productInfo.id, { isshow: true }).write()
|
|
|
+ }
|
|
|
+ // 获取json文件中的锁号,更新到exe当中
|
|
|
+ let downlist = await fse.readJsonSync(softwarejson).sc_down
|
|
|
+ for (let j in downlist) {
|
|
|
+ if (productInfo.readid === downlist[j].product_id && exeData.versionName === downlist[j].title) {
|
|
|
+ exeData.keyNumber = downlist[j].key_number
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ exeData.pid = '1'
|
|
|
+ exeData.keyNumber = ''
|
|
|
+ await db.read().get('sc_productData').updateById('1', { isshow: true }).write()
|
|
|
+ }
|
|
|
+ exeData.addtime = Date.parse(new Date()) / 1000
|
|
|
+ exeData.isshow = true
|
|
|
+ exeData.auto = true
|
|
|
+ ++globalNUM
|
|
|
+ await db.read().get('sc_exeData').insert(exeData).write()
|
|
|
+ } else {
|
|
|
+ await db.read().get('sc_productData').updateById(dbExeData.pid, { isshow: true }).write()
|
|
|
+ await db.read().get('sc_exeData').updateById(dbExeData.id, { isshow: true }).write()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ resolve()
|
|
|
+ })
|
|
|
+ // }, 1000)
|
|
|
+ })
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 判断系统位数
|
|
|
+ * @return {boolean}
|
|
|
+ */
|
|
|
+function isOSWin64 () {
|
|
|
+ return process.arch === 'x64' || process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432')
|
|
|
+}
|
|
|
+
|
|
|
+export default updateInstall
|