123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- 'use strict'
- /**
- * 读取注册表获取纵横软件
- *
- * @author EllisRan.
- * @date 2018/6/20
- * @version
- */
- import db from '../../database'
- 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
- let globalSoftware = []
- let globalExe = []
- 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 = []
- let promiseArr2 = []
- for (let i in softwarelist) {
- if (softwarelist[i].indexOf('SmartCost_') !== -1) {
- promiseArr2.push(getExeDataList(softwarelist[i]))
- }
- }
- await sleep(2000)
- await Promise.all(promiseArr2)
- .then(async function (result) {
- await sleep(5000)
- if (globalSoftware !== []) {
- console.log(globalSoftware)
- for (let i in globalSoftware) {
- (async function () {
- globalSoftware[i].exeName = globalExe[i]
- await promiseArr.push(insertData(globalSoftware[i]))
- })(i)
- }
- }
- let one = globalSoftware.length
- console.log(one)
- await sleep(2000)
- let two = globalSoftware.length
- console.log(two)
- if (one !== two) {
- console.log(globalSoftware)
- }
- await Promise.all(promiseArr)
- .then(async function (result) {
- // console.log(globalSoftware)
- 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 === '{}' || 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})
- // console.log(globalSoftware)
- } else {
- win.webContents.send('failedUpdate', {id: '1', error: 200})
- }
- globalNUM = 0
- globalSoftware = []
- globalExe = []
- })
- .catch(function (err) {
- win.webContents.send('failedUpdate', {id: '1', error: err})
- console.log(err)
- globalNUM = 0
- globalSoftware = []
- globalExe = []
- })
- })
- .catch(function (err) {
- console.log(err)
- })
- } catch (error) {
- console.log(error)
- }
- })
- })
- /**
- * 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()
- // }
- // 对还是isshow:false的软件进行文件夹文件查询,如果还在则保留,不存在则删除
- if (num !== 0) {
- let deleteExeData = await db.read().get('sc_exeData').filter({ auto: true, isshow: false }).value()
- for (let exe in deleteExeData) {
- let exePath = path.join(exe.path, exe.exeName)
- let existExe = await db.read().get('sc_exeData').find({ path: exe.path, exeName: exe.exeName, isshow: true }).value()
- if (fse.pathExistsSync(exePath) && !existExe) {
- db.read().get('sc_exeData').updateById(exe.id, { isshow: true }).write()
- }
- }
- }
- db.read().get('sc_exeData').removeWhere({ auto: true, isshow: false }).write()
- return num
- }
- const sleep = (timeout = 2000) => new Promise(resolve => {
- setTimeout(resolve, timeout)
- })
- // 取文件名不带后缀
- function GetFileNameNoExt (filepath) {
- if (filepath !== '') {
- let names = filepath.split('\\')
- let pos = names[names.length - 1].lastIndexOf('.')
- return names[names.length - 1].substring(0, pos)
- }
- }
- // 产生随机数函数
- function RndNum (n) {
- let rnd = ''
- for (let i = 0; i < n; i++) {
- rnd += Math.floor(Math.random() * 10)
- }
- return rnd
- }
- /**
- * 判断文件名是否包含纵横软件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
- }
- function inArray (val, arr) {
- for (let i in arr) {
- if (arr[i] === val) {
- return true
- }
- }
- return false
- }
- /**
- * 数据入库
- *
- */
- function insertData (exeData) {
- return new Promise(resolve => {
- let pathstr = path.join('data/fileInfo.dll')
- let libm = ffi.Library(pathstr, {
- 'GetFileInfo': ['string', ['string']]
- })
- let fileinfo = JSON.parse(libm.GetFileInfo(path.join(exeData.path, exeData.exeName)))
- exeData.fileVersion = fileinfo.FileVersion
- exeData.productName = fileinfo.ProductName
- exeData.productVersion = fileinfo.ProductVersion
- exeData.fileDescription = fileinfo.FileDescription
- let dbExeData = db.read().get('sc_exeData').find({ exeName: exeData.exeName, path: exeData.path, fileVersion: exeData.fileVersion }).value()
- if (dbExeData === undefined || dbExeData === null) {
- // 先判断是否存在该产品数据库(同时关联到sc_sofeware.json文件数据),再加入安装包数据库
- // 新方法,先关联注册表名查找数据,然后再关联产品数据库生成
- let softwarejson = path.join('data/sc_software.json')
- let downlist = fse.readJsonSync(softwarejson).sc_down
- let downinfo = downlist.find(function (item) {
- return inArray(exeData.regeditName, item.regedits)
- })
- // let ptitle = downinfo !== undefined ? downinfo.product_title : ''
- if (downinfo !== undefined) {
- exeData.simpleName = downinfo.product_title
- exeData.versionName = downinfo.title
- let productInfo = db.read().get('sc_productData').find({ product_id: downinfo.product_id }).value()
- if (productInfo === undefined || productInfo === null) {
- let scproductlist = fse.readJsonSync(softwarejson).sc_product
- let scproductInfo = scproductlist.find(function (item) {
- return item.product_id === downinfo.product_id
- })
- let productInfo2 = scproductInfo
- productInfo2.addtime = Date.parse(new Date()) / 1000
- productInfo2.isshow = true
- let insertproudct = db.read().get('sc_productData').insert(productInfo2).write()
- exeData.pid = insertproudct.id
- productInfo = insertproudct
- } else {
- exeData.pid = productInfo.id
- db.read().get('sc_productData').updateById(productInfo.id, { isshow: true }).write()
- }
- // 获取json文件中的锁号,更新到exe当中
- for (let j in downlist) {
- if (productInfo.product_id === downlist[j].product_id && exeData.versionName === downlist[j].title) {
- exeData.keyNumber = downlist[j].key_number
- exeData.keytype = downlist[j].keytype
- exeData.product_id = downlist[j].product_id
- exeData.down_id = downlist[j].down_id
- exeData.product_version = fileinfo.FileVersion
- exeData.show_tip = fileinfo.FileVesrion !== downlist[j].version && exeData.exeName !== 'BillsEditor.exe'
- exeData.show_updateVersion = downlist[j].version
- break
- }
- }
- } else {
- exeData.pid = '1'
- exeData.simpleName = ''
- exeData.versionName = ''
- exeData.keyNumber = ''
- exeData.keytype = ''
- exeData.product_id = ''
- exeData.down_id = ''
- exeData.product_version = ''
- exeData.show_tip = false
- exeData.show_updateVersion = ''
- db.read().get('sc_productData').updateById('1', { isshow: true }).write()
- }
- exeData.addtime = Date.parse(new Date()) / 1000
- exeData.isshow = true
- exeData.auto = true
- exeData.id = GetFileNameNoExt(exeData.exeName) + '-' + RndNum(10)
- ++globalNUM
- db.read().get('sc_exeData').insert(exeData).write()
- } else {
- db.read().get('sc_productData').updateById(dbExeData.pid, { isshow: true }).write()
- db.read().get('sc_exeData').updateById(dbExeData.id, { isshow: true }).write()
- }
- resolve(exeData)
- })
- }
- /**
- * 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 regeditData = {
- path: values['Inno Setup: App Path'].value,
- name: values['DisplayName'].value,
- regeditName: Info,
- fileName: values['Inno Setup: Icon Group'].value
- }
- let dirname = await fs.readdirSync(regeditData.path)
- for (let i in dirname) {
- if (path.extname(dirname[i]) === '.exe' && existSoftwareName(dirname[i])) {
- let exeData = regeditData
- // exeData.exeName = diraname[i]
- // 这里必须分离2个数组记录值并在外面合并,push才不会出错,否则会重复exeName名,未知bug,坑
- globalSoftware.push(exeData)
- globalExe.push(dirname[i])
- }
- }
- })
- resolve('ok')
- })
- }
- }
- /**
- * 判断系统位数
- * @return {boolean}
- */
- function isOSWin64 () {
- return process.arch === 'x64' || process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432')
- }
- export default updateInstall
|