【C#】条码管理操作手册
本文链接:https://blog.csdn.net/youcheng_ge/article/details/126589496
【C#】IIS平台下,WebAPI发布及异常处理
本文链接:https://blog.csdn.net/youcheng_ge/article/details/126539836
【C#】简单二维码制作和打印工具
本文链接:https://blog.csdn.net/youcheng_ge/article/details/126884228
【C#】最全单据打印源码(打印模板、条形码&二维码、字体样式、logo)
本文链接:https://blog.csdn.net/youcheng_ge/article/details/129415723
本文主要介绍,手持机(前文介绍过,可以理解为工业级手机)软件自动更新机制,为啥要这么做呢?是因为生产车间有很多台“手持机”,派运维一一更新不现实,加上系统初期,难免会有各种各样的问题,需要及时发布最新版到“手持机”。
我们“更新机制”采用最简单的C/S架构,服务端(Server)部署一个WebAPI,在指定目录下存放一个更新包,当手持机客户端连接服务端时,自动对比软件版本,如果不一致就“自动推送更新”。
后期补充
采用C# WebAPI创建项目,功能与前端手持机进行交互,负责处理手机持发来的数据、回传数据给手持机。我们项目Controllers文件夹下,创建控制类QRController.cs
查询数据库
【app版本信息表】
,获取最新的APP发布版本,以及安装提示信息
。
///
/// 获取app版本信息
///
/// ActionResult
[HttpGet]
public ActionResult GetAppVersion()
{
string l_strErrorCode = "C02";//错误码
ActionResult m_Result = new ActionResult();
string l_strSQL = "SELECT * FROM app版本信息表 ORDER BY AutoID DESC LIMIT 0,1;";
MySQLHelper MySQL = new MySQLHelper();
try
{
DataTable l_dtRetun = MySQL.Query(l_strSQL).Tables[0];
m_Result.Validate = true;
m_Result.RetInfo = new CRetInfo() { ErrorCode = l_strErrorCode + "1", IsSUCD = true, ErrorMsg = Const.ct_strFetchSuccess };
m_Result.Data = new CData() { Obj = null, Table = l_dtRetun, cByte = null, Tostring = "" };
}
catch (Exception ex)
{
m_Result.Validate = false;
m_Result.RetInfo = new CRetInfo() { ErrorCode = l_strErrorCode + "2", IsSUCD = false, ErrorMsg = Const.ct_strFetchFail + ex.Message };
m_Result.Data = new CData() { Obj = null, Table = null, cByte = null, Tostring = "" };
}
return m_Result;
}
控制器下载文件方法,向前端回传文件流。本方法负责下载apk文件到安装手机上。
不仅仅只能下载apk,任何文件都可以下载。
///
/// 文件下载-app自动更新机制
///
/// 文件字节流
[HttpGet]
public HttpResponseMessage DownloadFile(string a_fileName)
{
try
{
//文件的服务器地址
string filePath = HttpContext.Current.Server.MapPath("~/") + "filepath\\" + a_fileName;
if (!File.Exists(filePath))
{
return new HttpResponseMessage(HttpStatusCode.NotFound);
}
FileStream stream = new FileStream(filePath, FileMode.Open);
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new StreamContent(stream);
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = HttpUtility.UrlEncode(a_fileName)
};
response.Headers.Add("Access-Control-Expose-Headers", "FileName");
response.Headers.Add("FileName", HttpUtility.UrlEncode(a_fileName));
return response;
}
catch (Exception)
{
return new HttpResponseMessage(HttpStatusCode.NoContent);
}
}
在我们的IIS服务上,上传我们的最新apk包,因为我要既然要下载,肯定得有东西才能下载吧?
提示:这是我通过工具上传到服务器上的更新包,文件名:20230607.apk
前面,我们已经准备好了“文件下载方法”和“更新包文件”。现在我们开始测试,这里我使用【Postman工具】测试。
输入URL地址:http://192.168.XX.XX:8090/API/QR/DownloadFile?a_fileName=20230119.apk
状态200 ok,文件大小3.48M,说明服务器返回正常,
提示:这里乱码一样的东西不是报错哦!是回传回来的是 字节流,而工具暂时不支持,放在浏览器网页上执行就没有问题了。
这是网页执行效果,可以发现已经可以下载APK包了。
手持机采用HTML 5开发,这是前端的内容,另外讲解。
我写在通用js中,创建js文件,重命名common.js
//检查版本
function checkUpdate() {
api.ajax({
url : OpenAPI.GetAppVersion,
method : 'get',
headers: {
'Content-Type': 'application/json;charset=utf-8'//必须,否则后端无法识别
},
returnAll : false,
}, function(ret, err) {
if (ret) {
if (ret.RetInfo.IsSUCD) {// 取数成功
var l_tbResult = ret.Data.Table;
if (l_tbResult.length > 0) {
APPUpdate(l_tbResult[0]);
}
} else {// 取数失败
ShowToast(ret.RetInfo.ErrorCode+":"+ret.RetInfo.ErrorMsg);
}
} else {
api.alert({msg:err.msg});
}
});
}
common.js中,添加如下方法。
//app更新
function APPUpdate(l_data) {
var update = true;
var closed = false;
var version = l_data["version"];
var updateTip = l_data["updateTip"];
var source = l_data["source"];
var time = l_data["time"];
var appVersion = api.appVersion; //应用版本号
// 有更新:{update:true,closed:false}
if (update == true && closed == false && appVersion < version) {
var str = '新版本型号:' + version + ';\n更新提示语:' + updateTip + ';\n下载地址:' + source + ';\n发布时间:' + time;
api.confirm({
title : '有新的版本,是否下载并安装 ',
msg : str,
buttons : ['确定', '取消']
}, function(ret, err) {
if (ret.buttonIndex == 1) {
if (api.systemType == "android") {
api.download({
url : source,
report : true
}, function(ret, err) {
if (ret && 0 == ret.state) {/* 下载进度 */
api.toast({
msg : "正在下载应用" + ret.percent + "%",
duration : 2000
});
}
if (ret && 1 == ret.state) {/* 下载完成 */
var savePath = ret.savePath;
api.installApp({/* 安装app */
appUri : savePath
});
}
});
}
if (api.systemType == "ios") {
api.alert({
msg : "暂不支持"
});
}
}
});
} else {
api.alert({
msg : "暂无更新"
});
}
}
我的项目还在测试阶段,就分享给大家最新的成果。我目前在界面上增加了一个按钮,触发自动更新。
引入刚创建的js:
<script type="text/javascript" src="../script/common.js" >script>
按钮样式:
<li class="aui-list-item">
<div class="aui-list-item-inner" onclick="checkUpdate(true)">
<div class="aui-list-item-label">检查新版本div>
<div class="aui-list-item-right">
<i class="aui-iconfont aui-icon-right aui-collapse-arrow">i>
div>
div>
li>
数据库表:
-- ----------------------------
-- Table structure for app版本信息表
-- ----------------------------
DROP TABLE IF EXISTS `app版本信息表`;
CREATE TABLE `app版本信息表` (
`AutoID` bigint(20) NOT NULL AUTO_INCREMENT,
`version` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`versionDes` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`updateTip` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`source` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`time` datetime NULL DEFAULT NULL,
PRIMARY KEY (`AutoID`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;
SET FOREIGN_KEY_CHECKS = 1;
略