nw.js桌面程序自动更新(node.js表白记)
Hello Google
Node.js 一个基于Google V8 的JavaScript引擎。
一个伟大的端至端语言,或许我对你的热爱源自于web这门极富情感的技术吧!
注:
光阴似水,人生若梦,又是人间年尾。许久未说过如此矫情而生硬的话- -
如此篇幅实在无法写明白我扭曲的心理,2017望我还能继续迈进!
喜庆的话不多说,今天给大家分享一个大致3周前,初次涉足Node.js实现的nw.js桌面程序的自动更新模块吧。
本文不做教学,仅用于打脸!希望以此得到各位大神的帮助。
我本没有打算写如此博客来误人子弟,这里感谢@老毕(=^ ^=)
下面说的这个模块是基于angular.js的,如此粗鄙的几行代码,还望各位同仁瞄眼之后便使劲的喷!
一、机制分析
此机制的优劣性暂且不议,这仅是目前我唯一能想到的!
已经说了太多无聊的话,这个机制我就画个简单的草图来呈现吧。

从图中不难看出,我所谓的这个自动更新机制其实仅4步而已:
1.确定本地版本号与远端版本号
2.检测版本与平台
3.判断版本差异性
4.是否存在差异的进一步处理
二、模块实现
1.模块依赖
fs = require('fs');
path = require('path');
request = require('request');
child_process = require('child_process');
以下为依赖模块的简要释义:
fs: node.js 文件系统模块
path: node.js 文件路径模块
request: node.js http模块
child_process: node.js 子进程模块
2.版本对比(使用文件读写模块对本地版本号的写入与更新)
compareVer: function(RequestUrl) {
var remoteURL = RequestUrl;
var deferred = $q.defer();
fs.readFile(path.join(nwDir, 'version.txt'), function(err, data) {
if(err) {
fs.writeFile(path.join(nwDir, 'version.txt'), '0.0.1', function(err) {
if(err) throw err;
});
alert("系统检测到重要文件丢失,请手动重启应用!");
process.exit(0);
}else {
version.localVer = data;
$http.get(remoteURL).success(function(items) {
if(items.code == 200) {
version.remoteVer = items.data.version;
var isUpdate = version.localVer && version.remoteVer && version.localVer != version.remoteVer ? true : false;
items.isUpdate = isUpdate;
if(isUpdate) {
fs.writeFile(path.join(nwDir, 'version.txt'), version.remoteVer, function(err) {
if(err) throw err;
});
}
deferred.resolve(items);
}
}).error(function(data, status, headers, config) {
alert("程序初始化失败,请检查网络连接!");
});
}
});
return deferred.promise;
},
3.执行升级(使用http模块对差异版进行下载并执行文件流写入操作)
update: function(DownloadUrl, total) {
request(DownloadUrl, function (error, response) {
if(!error && response.statusCode == 200) {
angular.element('.title').html('升级完成');
angular.element('#progress > span').html('100');
$interval.cancel(timer);
var t = 3;
var interval = $interval(function() {
angular.element('.title').html('自动重启');
angular.element('#progress').html('<span style="font-size: 5em;">'+ t-- +'</span>');
if(t < 0) {
win.hide()
child_process.exec(file, function(err, stdout, stderr) {
process.exit(0);
});
$interval.cancel(interval);
}
}, 1000)
}
}).pipe(fs.createWriteStream(file));
var timer = $interval(function() {
var loaded = fs.statSync(file).size;
var percentComplete = loaded / total;
var downloadProgress = (percentComplete * 100).toFixed(1);
angular.element('#progress > span').html(downloadProgress);
}, 100);
return;
}
4.无差异性处理(隐藏主进程并创建子进程)
normal: function() {
win.hide();
child_process.exec(file, function(err, stdout, stderr) {
process.exit(0);
});
},
三、完整模块代码
/*
nw.js桌面程序自动更新module for angular
Author: BGONLINE
2016-12-29
*/
(function(angular, factory) {
if(typeof define === 'function' && define.amd) {
define('bgo-update', ['angular'], function(angular) {
return factory(angular);
});
}else {
return factory(angular);
}
}(typeof angular === 'undefined' ? null : angular, function(angular) { var module = angular.module('bgoUpdate', []); 'use strict'; module .factory('bgoAutoUpdate', ['$http', '$q', '$interval', '$timeout', function($http, $q, $interval, $timeout) {
var version = {
localVer: '',
remoteVer: ''
} var fs = require('fs');
var path = require('path');
var request = require('request');
var child_process = require('child_process');
var nwPath = process.execPath;
var nwDir = path.dirname(nwPath);
var file = path.join(nwDir, 'current.exe');
return {
normal: function() {
var str = '';
var interval = $interval(function() {
str += '.';
angular.element('#progress > span').html(str);
if(str.length > 3) {
win.hide()
child_process.exec(file, function(err, stdout, stderr) {
process.exit(0);
$interval.cancel(interval);
});
}
}, 1000)
}, compareVer: function(RequestUrl) {
var remoteURL = RequestUrl;
var deferred = $q.defer();
fs.readFile(path.join(nwDir, 'version.txt'), function(err, data) {
if(err) {
fs.writeFile(path.join(nwDir, 'version.txt'), '0.0.1', function(err) {
if(err) throw err;
});
layer.alert("系统检测到重要文件丢失,请手动重启应用!", {closeBtn: 0, icon: 5, shade: 0}, function() {
layer.closeAll();
process.exit(0);
});
}else {
version.localVer = data;
$http.get(remoteURL).success(function(items) {
if(items.code == 200) {
version.remoteVer = items.data.version;
var isUpdate = version.localVer && version.remoteVer && version.localVer != version.remoteVer ? true : false;
items.isUpdate = isUpdate;
if(isUpdate) {
fs.writeFile(path.join(nwDir, 'version.txt'), version.remoteVer, function(err) {
if(err) throw err;
});
}
deferred.resolve(items);
}
}).error(function(data, status, headers, config) {
layer.msg("程序初始化失败,请检查网络连接!", function() {});
});
} });
return deferred.promise;
}, update: function(DownloadUrl, total) {
request(DownloadUrl, function (error, response) {
if(!error && response.statusCode == 200) {
angular.element('.title').html('升级完成');
angular.element('#progress > span').html('100');
$interval.cancel(timer); var t = 3;
var interval = $interval(function() {
angular.element('.title').html('自动重启');
angular.element('#progress').html('<span style="font-size: 5em;">'+ t-- +'</span>');
if(t < 0) {
win.hide()
angular.element('.title').html('学籍系统保护模块');
angular.element('#progress > span').html('请勿关闭!');
child_process.exec(file, function(err, stdout, stderr) {
process.exit(0);
});
$interval.cancel(interval);
}
}, 1000)
}
}).pipe(fs.createWriteStream(file)); var timer = $interval(function() {
var loaded = fs.statSync(file).size;
var percentComplete = loaded / total;
var downloadProgress = (percentComplete * 100).toFixed(1);
angular.element('#progress > span').html(downloadProgress);
}, 100);
return;
}
}
}]) return module;
}));
四、模块调用
App.controller('UpdateController', ["$rootScope", "$scope", 'bgoAutoUpdate', function($rootScope, $scope, bgoAutoUpdate) {
bgoAutoUpdate.compareVer($rootScope.rootUrl + 'index/login/getVersion?platform=' + process.platform).then(function(res) { // 判断版本
$scope.isUpdate = res.isUpdate;
if($scope.isUpdate) {
bgoAutoUpdate.update(res.data.fileUrl, res.data.fileSize, res.data.version); // 执行更新
}else {
bgoAutoUpdate.normal();
}
});
}]);
如此可爱的node.js,感谢Google!
nw.js桌面程序自动更新(node.js表白记)的更多相关文章
- .Net桌面程序自动更新NAppUpdate
自动更新介绍 我们做了程序,不免会有版本升级,这就需要程序有自动版本升级的功能.应用程序自动更新是由客户端应用程序自身负责从一个已知服务器下载并安装更新,用户唯一需要进行干预的是决定是否愿意现在或以后 ...
- [Node.js] 01 - How to learn node.js
基本概念 链接:https://www.zhihu.com/question/47244505/answer/105026648 链接:How to decide when to use Node.j ...
- node.js学习(二)--Node.js控制台(REPL)&&Node.js的基础和语法
1.1.2 Node.js控制台(REPL) Node.js也有自己的虚拟的运行环境:REPL. 我们可以使用它来执行任何的Node.js或者javascript代码.还可以引入模块和使用文件系统. ...
- Edge.js:让.NET和Node.js代码比翼齐飞
通过Edge.js项目,你可以在一个进程中同时运行Node.js和.NET代码.在本文中,我将会论述这个项目背后的动机,并描述Edge.js提供的基本机制.随后将探讨一些Edge.js应用场景,它在这 ...
- io.js - 兼容 NPM 平台的 Node.js 新分支
io.js(JavaScript I/O)是兼容 NPM 平台的 Node.js 新分支,由 Node.js 的核心开发者在 Node.js 的基础上,引入更多的 ES6 特性,它的目的是提供更快的和 ...
- Windows 程序自动更新方案: Squirrel.Windows
Windows 程序自动更新方案: Squirrel.Windows 1. Squirrel Squirrel 是一组工具和适用于.Net的库,用于管理 Desktop Windows 应用程序的安装 ...
- EF-使用迁移技术让程序自动更新数据库表结构
承接上一篇文章:关于类库中EntityFramework之CodeFirst(代码优先)的操作浅析 本篇讲述的是怎么使用迁移技术让程序自动通过ORM框架将模型实体类结构映射到现有数据库,并新增或修改与 ...
- node.js day01学习笔记:认识node.js
Node.js(JavaScript,everywhere) 1.Node.js 介绍 1.1. 为什么要学习Node.js 企业需求 + 具有服务端开发经验更好 + front-end + back ...
- 性能追击:万字长文30+图揭秘8大主流服务器程序线程模型 | Node.js,Apache,Nginx,Netty,Redis,Tomcat,MySQL,Zuul
本文为<高性能网络编程游记>的第六篇"性能追击:万字长文30+图揭秘8大主流服务器程序线程模型". 最近拍的照片比较少,不知道配什么图好,于是自己画了一个,凑合着用,让 ...
随机推荐
- 【HighCharts系列教程】三、图表属性——chart
一.chart属性说明 Chart是HighCharts图表中主要属性,包括了图表区域的颜色.线条.高度.宽度.对齐.图表类型等诸多属性,也是HighCharts图表中必须配置的属性之一. 配置cha ...
- LVS+Keppalived实现高可用负载均衡
三.LVS Keppalived的安装 3.1.环境描述 LVS server1 (Master):10.0.0.202 虚拟IP为:10.0.0.210 LVS server2 ( Slave ) ...
- MySQL 索引的使用
一.or 的使用 (1)MySQL版本大于 5.x 的会使用 index merge 功能,即可以将多个单列索引集合起来使用,不过在查询时使用 or 的话,引擎为 myisam 的会开启 index ...
- JS中的事件大全
一般事件 onClick 鼠标点击事件,多用在某个对象控制的范围内的鼠标点击 onDblClick 鼠标双击事件 onMouseDown 鼠标上的按 ...
- Activiti----hellowWorld(使用H2数据库)
1.项目结构 2.pom <dependencies> <dependency> <groupId>junit</groupId> <artifa ...
- ZOJ 3931 Exact Compression
题目看了半小时才看懂的. 题意:首先根据给出的序列,构造出哈夫曼树,构造出来的是一棵二叉树,每个节点都有一个权值,每个节点的两个儿子只能取一个,问能否使取出来的节点权值之和刚好等于e. 这样一分析就很 ...
- VSC#2010打开视图编辑器假死/卡死
最近写项目代码的时候写C#,VSC#2010刚配置好,打开之前同学写的项目的设计界面结果...我擦,卡死了,重复几次都是这样. 于是上网搜发现是VS一个bug,打一个VSSP1补丁就好了~ http: ...
- 《算法导论》Problem 2-4 Inversions
在Merge Sort的基础上改改就好了. public class Inversions { public static int inversions(int [] A,int p, int r) ...
- iOS开发——工厂模式
工厂模式很好用,为表诚意,我直接搞个实用的例子放这,解析一个订单的数据,并且这个订单里面可能不止一件商品的做法. 还是直接上代码,不懂的地方,再提出来. 1.在MyOrderDeals.h文件中 #i ...
- 功率W与dBm的对照表及关系(转)
源:功率W与dBm的对照表及关系 功率W与dBm的对照表 dBm Watts dBm Watts 0 ...