exe-install.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. 'use strict'
  2. /**
  3. * 软件安装检测
  4. *
  5. * @author EllisRan.
  6. * @date 2018/8/9
  7. * @version
  8. */
  9. import db from '../../database'
  10. const path = require('path')
  11. const ffi = require('ffi')
  12. const fs = require('fs')
  13. const electron = require('electron')
  14. const ipcMain = electron.ipcMain
  15. const regeditPath64 = 'HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'
  16. const regeditPath32 = 'HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall'
  17. const regeditPath = isOSWin64() ? regeditPath64 : regeditPath32
  18. const regedit = require('regedit')
  19. const exeinstall = function (win) {
  20. ipcMain.on('checkExeInstall', (event, args) => {
  21. let info = args.info
  22. try {
  23. // 先检查数据库中是否已存在该注册表软件的信息,有则退出,无则继续
  24. let exesqlinfo = db.read().get('sc_exeData').find({ regeditName: info.regedit, fileVersion: info.version }).value()
  25. if (exesqlinfo !== undefined) {
  26. event.sender.send('InstallResult', { status: 400, msg: `启动器已存在相同版本的 ${info.fulltitle} 软件`, id: info.id, index: args.index })
  27. } else {
  28. let regeditpath = path.join(regeditPath, info.regedit)
  29. regedit.list(regeditpath, async function (err, result) {
  30. if (err === null && result !== undefined) {
  31. let values = result[regeditpath].values
  32. let regeditMsg = {
  33. path: values['Inno Setup: App Path'].value,
  34. name: values['DisplayName'].value,
  35. regeditName: info.regedit,
  36. fileName: values['Inno Setup: Icon Group'].value,
  37. simpleName: info.product_title,
  38. versionName: info.title,
  39. keyNumber: info.key_number,
  40. keytype: info.keytype,
  41. isshow: true,
  42. auto: false,
  43. pid: info.pid,
  44. product_id: info.product_id,
  45. down_id: info.down_id,
  46. product_version: info.version,
  47. show_tip: false,
  48. show_updateVersion: info.version
  49. }
  50. let data = await checkDirectory(regeditMsg.path)
  51. for (let i = 0; i < data.length; i++) {
  52. let exeinfo = regeditMsg
  53. exeinfo.exeName = data[i].exeName
  54. exeinfo.fileVersion = data[i].FileVersion
  55. exeinfo.productName = data[i].ProductName
  56. exeinfo.productVersion = data[i].ProductVersion
  57. exeinfo.fileDescription = data[i].FileDescription
  58. exeinfo.addtime = Date.parse(new Date()) / 1000
  59. db.read().get('sc_exeData').insert(exeinfo).write()
  60. }
  61. db.read().get('sc_productData').updateById(info.pid, { isshow: true }).write()
  62. await db.read().get('sc_productData').updateById(info.pid, { isshow: true }).write()
  63. await db.read().set('sc_hadInstall.url', '/softwarestartup/' + info.pid).write()
  64. event.sender.send('InstallResult', { status: 200, msg: data.length, id: info.id, index: args.index })
  65. win.webContents.send('successUpdate', { id: info.pid, num: data.length, delnum: 0 })
  66. } else {
  67. event.sender.send('InstallResult', { status: 400, msg: `未能成功安装 ${info.fulltitle} 软件`, id: info.id, index: args.index })
  68. }
  69. })
  70. }
  71. } catch (err) {
  72. event.sender.send('InstallResult', { status: 400, msg: err, id: info.id, index: args.index })
  73. }
  74. })
  75. /**
  76. * 判断文件名是否包含纵横软件exe的部分名称
  77. * @param item
  78. * @return {boolean}
  79. */
  80. function existSoftwareName (item) {
  81. // 纵横软件exe所带包含的文件名
  82. const smartcostSoftwareHeader = ['SmartCost', 'Measure', 'DrawingBuilder', 'BillsEditor']
  83. let flag = false
  84. for (let i = 0; i < smartcostSoftwareHeader.length; i++) {
  85. if (item.indexOf(smartcostSoftwareHeader[i]) !== -1) {
  86. flag = true
  87. break
  88. }
  89. }
  90. return flag
  91. }
  92. /**
  93. * 检查文件夹并判断是否包含纵横软件(一个文件可能存在多个纵横软件的)
  94. * @param files
  95. * @return {Promise.<Array>}
  96. */
  97. async function checkDirectory (files) {
  98. let data = []
  99. let dirname = await fs.readdirSync(files)
  100. dirname.forEach(async function (item, index) {
  101. if (path.extname(item) === '.exe' && existSoftwareName(item)) {
  102. let pathstr = path.join('data/fileInfo.dll')
  103. let libm = ffi.Library(pathstr, {
  104. 'GetFileInfo': ['string', ['string']]
  105. })
  106. let fileinfo = JSON.parse(await libm.GetFileInfo(path.join(files, item)))
  107. fileinfo.exeName = item
  108. data.push(fileinfo)
  109. }
  110. })
  111. return data
  112. }
  113. }
  114. /**
  115. * 判断系统位数
  116. * @return {boolean}
  117. */
  118. function isOSWin64 () {
  119. return process.arch === 'x64' || process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432')
  120. }
  121. export default exeinstall