在很多企业使用的程序都是不能通过微软商店发布,原因很多,其中我之前的团队开发了很久的应用,结果发现没有用户能从微软应用商店下载所以我对应用商店没有好感。但是作为一个微软粉丝,怎么能不支持 UWP 开发呢。但是做出来 UWP 应用还是需要用户能用,经过了很长的时间,和很多大佬聊了之后,终于对新的项目使用旁加载的方式,使用自己的服务器提供下载更新

本文告诉大家如何搭建一个 asp dotnet core 服务器,将一个 UWP 程序使用旁加载发布,同时支持自动更新

首先创建一个简单的 UWP 程序,这个程序显示当前的包的版本,通过程序的包的版本就可以知道是否更新成功。

在 17134 也就是系统的版本是 1803 的时候,就支持自动更新 UWP 应用,因为我所在的团队的客户的系统都是可以控制的,于是全部都升级到 1803 的系统。

虽然旁加载对于证书不是很友好,但是因为我的应用都是预装的,本来的两大问题一个就是自动更新问题,另一个是从应用商店下载的问题,通过预装可以解决应用商店下载问题。解决了下载的坑,最大的问题在于更新问题,如果能使用自己的服务器,那么在国内更新是没有网络问题

如果小伙伴不是使用预装,那么也可以自己写一个简单的安装程序,这里就不说了

在 UWP 获取当前的软件版本可以使用下面代码

        private static string GetVersion()
{
Package package = Package.Current;
PackageId packageId = package.Id;
PackageVersion version = packageId.Version; return $"{version.Major}.{version.Minor}.{version.Build}.{version.Revision}";
}

在界面创建简单的代码,请看代码

        public MainPage()
{
this.InitializeComponent();
((Grid) Content).Children.Add(new TextBlock()
{
Text = GetVersion(),
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center
});
}

现在尝试右击项目创建包,选择旁加载

这里只是做演示,所以只勾选 x86 的,这样创建速度比较快

点击下一步,在这里写入 URL 这里需要拿到本地的内网的 IP 这样在可以在后面在其他的设备安装 UWP 应用,我这里已经写上了自己的 IP 和端口号,还有一个路径

在本文下面将会告诉大家如何让 asp dotnet core 程序支持上面的路径下载程序,当然需要将 IP 修改为你的内网IP才可以

不等待 VisualStudio 编译,先创建一个 asp dotnet core 程序

选择创建 api 程序,注意不要打开 https 这样比较快,如何创建请看win10 uwp 手把手教你使用 asp dotnet core 做 cs 程序

打开 Startup 文件,在 Configure 添加静态文件的支持,因为旁加载发布的就是文件

在 asp dotnet core 打开静态文件支持,就可以让访问网页的小伙伴直接下载文件,如我将旁加载的内容放在E:\package 文件夹,那么我就需要设置这个文件夹可以在网页被访问,里面的文件访问到就可以下载

            app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider("E:\\package"),
RequestPath = "/package",
});

因为现在可能 VisualStudio 还没编译完成,所以先尝试在 E:\package 放一个文件,如 1.txt 在里面随意写一点内容,然后调试 asp dotnet core 程序,在地址写上 http://localhost:端口/package/1.txt 每个项目调试的端口都不一样,请自己将端口修改为调试的端口,然后看是不是能看到 1.txt 写入的内容

大概现在 UWP 程序已经编译完成,将编译的文件复制到 E:\package 文件夹,可以看到里面的文件有很多 asp dotnet core 不认识的文件,在 asp dotnet core 如果想要让用户下载某个文件,需要设置这个文件的 IMME 只需要创建 FileExtensionContentTypeProvider 就会添加很多已知的文件,如刚才访问的 txt 文件

│  DoucoujaWeasaikibeaDreecoVorkehear.appinstaller
│ index.html

└─DoucoujaWeasaikibeaDreecoVorkehear_1.0.1.0_Debug_Test
│ Add-AppDevPackage.ps1
│ DoucoujaWeasaikibeaDreecoVorkehear_1.0.1.0_x86_Debug.appxbundle
│ DoucoujaWeasaikibeaDreecoVorkehear_1.0.1.0_x86_Debug.appxsym
│ DoucoujaWeasaikibeaDreecoVorkehear_1.0.1.0_x86_Debug.cer

├─Add-AppDevPackage.resources
│ │ Add-AppDevPackage.psd1
│ │
│ ├─cs-CZ
│ │ Add-AppDevPackage.psd1
│ │
│ ├─de-DE
│ │ Add-AppDevPackage.psd1
│ │
│ ├─en-US
│ │ Add-AppDevPackage.psd1
│ │
│ ├─es-ES
│ │ Add-AppDevPackage.psd1
│ │
│ ├─fr-FR
│ │ Add-AppDevPackage.psd1
│ │
│ ├─it-IT
│ │ Add-AppDevPackage.psd1
│ │
│ ├─ja-JP
│ │ Add-AppDevPackage.psd1
│ │
│ ├─ko-KR
│ │ Add-AppDevPackage.psd1
│ │
│ ├─pl-PL
│ │ Add-AppDevPackage.psd1
│ │
│ ├─pt-BR
│ │ Add-AppDevPackage.psd1
│ │
│ ├─ru-RU
│ │ Add-AppDevPackage.psd1
│ │
│ ├─tr-TR
│ │ Add-AppDevPackage.psd1
│ │
│ ├─zh-CN
│ │ Add-AppDevPackage.psd1
│ │
│ └─zh-TW
│ Add-AppDevPackage.psd1

└─Dependencies
├─arm
│ Microsoft.NET.CoreFramework.Debug.2.2.appx
│ Microsoft.NET.CoreRuntime.2.2.appx
│ Microsoft.VCLibs.ARM.Debug.14.00.appx

├─ARM64
│ Microsoft.VCLibs.ARM64.Debug.14.00.appx

├─x64
│ Microsoft.NET.CoreFramework.Debug.2.2.appx
│ Microsoft.NET.CoreRuntime.2.2.appx
│ Microsoft.VCLibs.x64.Debug.14.00.appx

└─x86
Microsoft.NET.CoreFramework.Debug.2.2.appx
Microsoft.NET.CoreRuntime.2.2.appx
Microsoft.VCLibs.x86.Debug.14.00.appx

在 UWP 的安装对于这些文件有诡异的要求,如 appinstaller 需要是 application/xml 对于 appxappxbundle 需要是 application/vns.ms-appx 才能安装

            app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider("E:\\package"),
RequestPath = "/package",
DefaultContentType = "application/octet-stream",
ServeUnknownFileTypes = true,
ContentTypeProvider = new FileExtensionContentTypeProvider()
{
Mappings =
{
{".appinstaller", "application/xml"},
{".appx", "application/vns.ms-appx"},
{".appxbundle", "application/vns.ms-appx"},
}
}
});

如果小伙伴不想使用 E:\package 作为存放 UWP 安装包的文件夹,那么可以修改为自己本地的可以访问的文件夹,同时访问的 URL 链接不变,因为设置 URL 的链接是通过 RequestPath 属性。如我将 RequestPath 修改为 /csdn 那么就需要从 http://ip:端口/csdn/文件 才可以

还看到了有 index.html 文件,打开默认文件,这样访问 package 就可以看到 index.html 文件

现在的 asp dotnet core 的代码请看下面

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} app.UseDefaultFiles(); app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider("E:\\package"),
RequestPath = "/package",
DefaultContentType = "application/octet-stream",
ServeUnknownFileTypes = true,
ContentTypeProvider = new FileExtensionContentTypeProvider()
{
Mappings =
{
{".appinstaller", "application/xml"},
{".appx", "application/vns.ms-appx"},
{".appxbundle", "application/vns.ms-appx"},
}
}
}); app.UseMvc();
}

此时访问 http://localhost:端口/package/index.html 能看到下面界面

当然因为大家创建的测试的 UWP 程序的命名不一样,看到界面也有一些不一样

但是现在还是无法安装的,因为安装程序是 UWP 程序,发布的 asp dotnet core 是本地网络,但是 UWP 程序无法直接访问本地网络,所以要么修改让 UWP 可以访问本地网络,要么拿小伙伴的设备访问,刚好我就拿了小伙伴的设备

如果想要让安装程序访问本地网络,请在命令行输入下面代码

CheckNetIsolation.exe LoopbackExempt -a -n="microsoft.desktopappinstaller_8wekyb3d8bbwe"

要让小伙伴的设备可以访问你的 asp dotnet core 程序,就需要在 asp dotnet core 设置使用的 URL 和端口

使用下面的代码可以修改 asp dotnet core 监听端口

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseUrls("http://0.0.0.0:5000")
.UseStartup<Startup>();

这里使用 0.0.0.0 就是能访问到本机的所有 Ip 如 127.0.0.1 或内网 ip 都可以,上面的代码写在 Program 文件,请不要随意更改设置的端口,应该刚才的 UWP 程序就使用了这个端口

现在重新编译一下,然后通过命令行运行 dotnet core 程序,然后告诉小伙伴你的本地的 ip 让在浏览器输入

我的小伙伴使用不清真的 Chrome 访问,但是他不能立刻点获取应用

因为他需要先下载证书,在使用旁加载就需要手动安装证书,因为测试程序使用的证书是不可信的,点击其他链接,下载证书

打开证书,然后点击安装证书,选放在本地计算机

然后点击将所有的证书放在受信任的根证书颁发

点击完成

现在点击获取应用,等待安装,现在就可以看到下面界面

那么如何做到自动更新,刚才创建的时候设置是每次打开的时候都判断有没有可以更新的,现在尝试点击打包,自动会更新版本号

于是将打包的文件复制到 E:\package 文件夹,注意 appinstaller 文件也需要复制,这个文件就是自动更新的核心

复制过去之后,在小伙伴的设备关闭测试的 UWP 程序,再打开,此时可以从命令行看到有程序访问 asp dotnet core 程序

关闭测试的 UWP 程序,再次打开发现这个程序已经是 1.0.2 请看下面

看起来自己做一个服务器让用户安装 UWP 程序还是很简单的

但是有一个问题是 UWP 如何知道可以更新了?其实用 VisualStudio 打开 appinstaller 文件就知道了,这个文件是 xml 文件,里面写了 MainBundle 的路径,于是判断当前的程序版本比服务器的小,就从服务器下载安装

总结

  1. 需要最低版本是 17134 用户的设备是 1803 版本

  2. 因为 UWP 安装程序是 UWP 程序不能访问本机网络,建议测试的时候拿小伙伴的设备

  3. 在 asp dotnet core 服务器需要修改 appinstaller 和 appx 文件才能下载

  4. 需要先安装证书为可信任同时放在本地计算机才可以安装

  5. 更新的时候需要更新 appinstaller 文件才能自动更新

通过这个方法,我在很多用户的设备安装了应用,而不需要将应用放在应用商店,这样我可以控制用户下载,控制用户下载的方法通过 asp dotnet core 判断用户访问了 appinstaller 文件,通过控制权限的方法,返回不同的 appinstaller 文件,这样有一些用户就发现版本是新的,下载新的程序,有一些用户发现还是之前的版本,于是就不会下载

现在开发 UWP 感觉还是不错的,虽然没有多少用户会使用应用商店,但是通过本文告诉大家的方法是不需要应用商店,只需要一个服务器,但是大家可以看到安装界面不好看,那么就需要小伙伴自己去写安装程序

如何在国内发布 UWP 应用

我搭建了自己的博客 https://blog.lindexi.com/ 欢迎大家访问,里面有很多新的博客。只有在我看到博客写成熟之后才会放在csdn或博客园,但是一旦发布了就不再更新

如果在博客看到有任何不懂的,欢迎交流,我搭建了 dotnet 职业技术学院 欢迎大家加入


本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

win10 uwp 发布旁加载自动更新的更多相关文章

  1. 2019-11-25-win10-uwp-发布旁加载自动更新

    原文:2019-11-25-win10-uwp-发布旁加载自动更新 title author date CreateTime categories win10 uwp 发布旁加载自动更新 lindex ...

  2. 2019-3-1-win10-uwp-发布旁加载自动更新

    title author date CreateTime categories win10 uwp 发布旁加载自动更新 lindexi 2019-03-01 09:40:27 +0800 2019-0 ...

  3. Intellij IDEA热加载更新 IntelliJ IDEA热加载自动更新(Update classes and resources )

    定义及分类 1.1 定义 在web开发环境下,所谓热部署,即在不重新部署webapp的情况下,实时将工程代码改动更新到web容器中(例如tomcat).其原理可以类比ajax的作用,即局部刷新工程资源 ...

  4. IntelliJ IDEA热加载自动更新(Update classes and resources )

          IntelliJ IDEA默认文件是自动保存的,但是手头有个项目jsp文件改动后,在tomcat中不能立即响应变化.想要jsp文件改动后立刻看到变化,可以通过修改配置来实现.       ...

  5. 获取 windows 商店内的 aapx 安装包 并 安装(旁加载)

    这是一篇教程,写在 win10 版<量子破碎>发售近期. 主要原因:windows 商城的应用下载实在难以忍受...... #######2016-4-9更新####### 4-6号通过旁 ...

  6. 2019-11-25-win10-uwp-通过命令行脚本开启旁加载

    原文:2019-11-25-win10-uwp-通过命令行脚本开启旁加载 title author date CreateTime categories win10 uwp 通过命令行脚本开启旁加载 ...

  7. Hololens生成与安装(旁加载)应用

    Hololens生成应用的几种方式: 一:HoloToolkit编辑器生成appx应用 二:Vistul Studio 2015 创建应用 旁加载概述: 你可以将应用旁加载到你的设备,而无需将它们提交 ...

  8. Ztree异步加载自动展开节点

    在Ztree的官网Demo中,有自动展开的例子,是通过设置节点属性open:true来实现自动展开的,但是在异步加载中,这个属性设置为true也不会自动展开,因为open:true是指在有子节点的情况 ...

  9. 安装KB3132372补丁后,WIN10中IE内核加载flash崩溃

    今天(2015年12月30日)突然很多人反馈在WIN10上IE内核的PC端应用崩溃.经过一番查找,最终定位到问题.WIN10今天发布了新的补丁KB3132372,64位系统更新该补丁后,打开IE内核的 ...

随机推荐

  1. PHP核心编程-图像操作

    一 图像操作环境: 1.    开启GD2图像处理并检测 在php.ini开启GD库 2.    画布坐标系说明 二. 图像基本操作(步骤) 1.    创建图像 创建画布(图像资源) 创建的方法: ...

  2. PHP学习(mysqli函数)

    php是一种运行在服务器端的程序语言,用于生产动态网页内容.特点:开源,简单,易上手,跨平台(windows,linux),占用资源少,尤其适合中小型应用开发.(微博,微信,论坛等等)一,搭建软件环境 ...

  3. vue中element-ui添加按钮

    <div v-for="(v,i) in list"> <el-form label-width="120px" size="sma ...

  4. Directx11教程(12) 禁止alt+enter全屏窗口

    原文:Directx11教程(12) 禁止alt+enter全屏窗口        在D3D11应用程序中,我们按下alt+enter键,会切换到全屏模式.有时候,我们在WM_SIZE中有一些代码,全 ...

  5. 使用PHP类TCPDF生成PDF文档

    转自:http://www.blhere.com/1180.html 这两天遇到一个项目中,需要php自动处理生成pdf文档.在网上找了好几个类,最后决定使用TCPDF,使用的时候真是发现这个类真是强 ...

  6. hackerrank---Sets - Symmetric Difference

    题目链接 集合操作 附上代码: M = int(input()) m = set(map(int, raw_input().strip().split())) N = int(input()) n = ...

  7. LeetCode208 Implement Trie (Prefix Tree). LeetCode211 Add and Search Word - Data structure design

    字典树(Trie树相关) 208. Implement Trie (Prefix Tree) Implement a trie with insert, search, and startsWith  ...

  8. 【Mysql的那些事】数据库之ORM操作

    1:ORM的基础操作(必会) <1> all(): 查询所有结果 <2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 <3> get(* ...

  9. pytorch 多GPU训练总结(DataParallel的使用)

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/weixin_40087578/artic ...

  10. Java面向对象----接口概念

    接口语法 interface 接口名{ //静态常量,抽象方法 } 特点 接口中只能存放静态常量和抽象方法 java接口是对功能的扩展 通过实现接口,java类可以实现多实现 一个类可以同时继承(ex ...