迁移桌面程序到MS Store(7)——APPX + Service
本篇我们以一个Sample工程,来说明如何把一个常见结构的desktop application,转制成APPX并在MS Store提供下载。

之前的篇章中,我们已经介绍了一些内容,包括如何通过Visual Studio创建Packaging工程, 如何将Class Libraries转换到.NET Standard版本。至此,UI界面,以及部分DLL的迁移问题得到解决。但有时候我们的desktop application还包括一个本地的Background Service。那么目前微软推荐的策略,依然是通过创建一个WCF服务,然后host在Windows Service上,来提供给前端的APPX访问。
可能有同学要问,为什么我们需要Windows Service。这是因为在前台程序中,一般不会要求admin权限,这在企业级软件中是较为常见的需求,用PowerPiont的普通员工,通常被认为即没有power也没有point,更不需要admin权限……(悲剧啊T_T)但我们可以把需要admin权限,访问硬件等相关操作,放到Service中,由IT统一部署到机器上,避免了没有admin权限无法正常运行程序的问题。
在接下来的Sample中,我们试图通过代码启动一个Windows服务"aspnet_state"。这个工程非常的简单,我们要做的仅仅是在UWP project中调用一下Windonws Service上运行的WCF服务。工程结构如下图。因为工程主要想说明UI程序对WCF服务的引用,所以请不要在意使用UI程序是UWP还是WPF。实际使用中,对于Desktop Bridge的程序,非WCF的其他Background Service也是可以的,比如Named Pipes等。

我们的UI部分非常的简单,仅是在MainPage.cs中调用WCF服务中提供的方法,这里我们可以看到传递了一个string类型的参数作为要启动的service name。
public sealed partial class MainPage : Page
{
private string serviceName = "aspnet_state";
private LocalServiceClient client = new LocalServiceClient(); public MainPage()
{
this.InitializeComponent();
} private async void Button_Click(object sender, RoutedEventArgs e)
{
var status = await client.StartServiceAsync(serviceName);
textBlockStatus.Text = status.ToString();
}
}
如何编写WCF服务这里就不赘述了,有兴趣的同学可以去MSDN上学习:
https://docs.microsoft.com/en-us/dotnet/framework/wcf/index
同样直接给出如何将WCF服务host在Windows Service上的链接:
https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-host-a-wcf-service-in-a-managed-windows-service
在WCF service的代码里,我们通过ServiceController启动另一个系统的Windows Service,需要注意的是,我们测试用的"aspnet_state"默认是未开启的,而启动Windows Service要求程序具有admin权限。

public class LocalServiceWrapper : ILocalService
{
public ServiceControllerStatus StartService(string name)
{
ServiceController controller = new ServiceController(name); if (controller.Status == ServiceControllerStatus.Stopped)
{
controller.Start();
controller.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds());
}
return controller.Status;
}
}
你也可以试试Bluetooth Support Service,Service name是"bthserv"。通过程序开启蓝牙服务似乎更合理,但反复测试disable/enable蓝牙让我很烦躁。所以最终我换成了"aspnet_state"。
把程序拆分成UI和WCF Service两部分的目的,是将需要admin权限等不符合MS Store审核要求的代码,从APPX中移出,已servcie的形式来调用。最终的结构图可以分为两种。
第一种是采用Desktop Bridge的形式,APPX部分可以继续包含native C++ libraries,也可以调用任何形式的background service。唯一的问题是,在提交APPX到商店审核的时候,需要申请相应权限。企业级的软件通过审核的可能性很大,个人作品就不清楚了。审核通过后APPX获得微软的签名。此时用户可从商店下载APPX,然后手动安装Service部分。也可以由公司IT以Sideload的方式统一安装APPX+Service。

第二种更为纯粹,由UWP+.NET Standard+WCF组成,相应也需要更多的改动,而Native C++ Libraries的部分则需要下沉到Service中。这种的好处在于迁移的更为彻底,对未来有着更好的适应。当然哪天某软翻脸不认账,抛弃UWP又回头去搞.NET Core的WPF的话,你就当我没说过……

本篇讨论了如何将现有的desktop application,在维持已有架构的前提下,转制成APPX放到MS Store提供下载。
当然你们会觉得多出来的Service部分简直不能忍。后续我会进一步介绍如何处理Service部分,不至于让强迫症患者在评论里骂我……
本篇Sample工程的GitHub链接:
https://github.com/manupstairs/UWPWithWCFSample
迁移桌面程序到MS Store(7)——APPX + Service的更多相关文章
- 迁移桌面程序到MS Store(8)——通过APPX下载Win32Component
在上一篇<迁移桌面程序到MS Store(7)——APPX + Service>中,我们提到将desktop application拆分成UI Client+Service两部分.其中UI ...
- 迁移桌面程序到MS Store(9)——APPX With Desktop Extension
在<迁移桌面程序到MS Store(8)——通过APPX下载Win32Component>中我们讨论了通过APPX来下载Service部分的安装包.但是纯UWP的客户端并不能自动运行下载的 ...
- 迁移桌面程序到MS Store(14)——APPX嵌入WCF Service以Admin权限运行
Windows10 1809版本开始,微软又对UWP开放了新的Capability:AllowElevation. 通过这个新的Capability,UWP APP能够在运行时向用户请求Admin权限 ...
- 迁移桌面程序到MS Store(5)——.NET Standard
接下来的几篇,我想讨论下迁移桌面程序到MS Store,可以采用的比较常见.通用性比较强的实施步骤和分层架构. 通常商业项目一般都是不断的迭代,不太可能突然停止更新现有的桌面版本,然后花很长时间从头来 ...
- 迁移桌面程序到MS Store(1)——通过Visual Studio创建Packaging工程
之前跑去做了一年多的iOS开发,被XCode恶心得不行.做人呢,最重要的是开心.所以我就炒了公司鱿鱼,挪了个窝回头去做Windows开发了. UWP什么的很久没有正儿八经写了,国内的需求 ...
- 迁移桌面程序到MS Store(10)——在Windows S Mode运行
首先简单介绍Windows 10 S Mode,Windows在该模式下,只能跑MS Store里的软件,不能通过其他方式安装.好处是安全有保障,杜绝一切国产流氓软件.就像iOS一样,APP进商店都需 ...
- 迁移桌面程序到MS Store(12)——WPF使用UWP InkToolbar和InkCanvas
我们在<迁移桌面程序到MS Store(4)——桌面程序调用Win10 API>提到了对Win10 API的调用,但仍存在无法在WPF中使用UWP控件的问题,虽然都是XAML控件,但却是两 ...
- 迁移桌面程序到MS Store(13)——动态检查Win10 API是否可用
假设我们现有一个WPF程序,需要支持1903以前的Windows 10版本.同时在1903以后的版本上,额外多出一个Ink的功能.那么我们就可以通过ApiInformation.IsApiContra ...
- 迁移桌面程序到MS Store(2)——Desktop App Converter
迁移传统桌面程序到MS Store的另一种方式是使用Desktop App Converter工具.虽然本篇标题包含了Desktop App Converter(以下简称DAC),实际上我是来劝你别用 ...
- 迁移桌面程序到MS Store(3)——开机自启动
迁移桌面程序的时候,有可能你会遇到这么个需求——开机自启动.Windows传统桌面程序的传统陋习.不论什么奇葩软件都想要开机自启动,默认就给你打开,一开机哐哐哐什么雷,什么企鹅都蹦出来,也不管你用不用 ...
随机推荐
- pc-H5 适配方案
一.介绍 在前端项目页面开发中,尤其是H5页面开发,我们常常要适配各种分辨率的屏幕,才能让用户获得最好的体验效果.pc也是如此,很多页面是一屏,也是要适配各种尺寸的分辨率.这时候我们就需要对各种分辨率 ...
- Python3实战系列之四(获取印度售后数据项目)
问题:续接上一篇.说干咱就干呀,勤勤恳恳写程序呀! 目标:此篇开始进入正题了.为实现我们整个项目功能而开始实现各个子模块功能.首先实现第一篇列出的分步功能模块的第一步: 1.python访问ftp,下 ...
- Vue 汇总
1.右键菜单(防止默认行为) @contextmenu.native.prevent="rightClick()"
- jQuery 2
<head > <style type="text/css"> /*table中偶数行*/ .tabEven { bac ...
- ManageEngine的EventLog Analyzer许可信息
- mysql之练习题4
准备表: create table class(cid int primary key auto_increment, caption ) not null unique); INSERT into ...
- 2018.11.06 bzoj2287: 【POJ Challenge】消失之物(背包)
传送门 先假设所有物品都能用,做01背包求出方案数. 然后枚举每个点,分类讨论扣掉它对答案的贡献. 代码: #include<bits/stdc++.h> using namespace ...
- Winform自定义表单(转)
出处:http://www.newlifex.com/showtopic-167.aspx 好吧,附件真的损坏了,原始代码我也没有了,再提取我也没精力了,不好意思,哪位之前下过可以重发一遍吗?不过即使 ...
- ant Design和ant Design mobile的使用,并实现按需加载
1.全局安装yarn npm install -g create-react-app yarn 2.创建react项目,并用yarn start 运行 3.引入antd/引入antd-mobile y ...
- Oracle修改数据库的日期
---Oracle数据库更新时间字段数据时的sql语句---格式化时间插入 update t_invite_activityinfo set endtime=to_date('2019-10-30 1 ...