本篇我们以一个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的更多相关文章

  1. 迁移桌面程序到MS Store(8)——通过APPX下载Win32Component

    在上一篇<迁移桌面程序到MS Store(7)——APPX + Service>中,我们提到将desktop application拆分成UI Client+Service两部分.其中UI ...

  2. 迁移桌面程序到MS Store(9)——APPX With Desktop Extension

    在<迁移桌面程序到MS Store(8)——通过APPX下载Win32Component>中我们讨论了通过APPX来下载Service部分的安装包.但是纯UWP的客户端并不能自动运行下载的 ...

  3. 迁移桌面程序到MS Store(14)——APPX嵌入WCF Service以Admin权限运行

    Windows10 1809版本开始,微软又对UWP开放了新的Capability:AllowElevation. 通过这个新的Capability,UWP APP能够在运行时向用户请求Admin权限 ...

  4. 迁移桌面程序到MS Store(5)——.NET Standard

    接下来的几篇,我想讨论下迁移桌面程序到MS Store,可以采用的比较常见.通用性比较强的实施步骤和分层架构. 通常商业项目一般都是不断的迭代,不太可能突然停止更新现有的桌面版本,然后花很长时间从头来 ...

  5. 迁移桌面程序到MS Store(1)——通过Visual Studio创建Packaging工程

    之前跑去做了一年多的iOS开发,被XCode恶心得不行.做人呢,最重要的是开心.所以我就炒了公司鱿鱼,挪了个窝回头去做Windows开发了.        UWP什么的很久没有正儿八经写了,国内的需求 ...

  6. 迁移桌面程序到MS Store(10)——在Windows S Mode运行

    首先简单介绍Windows 10 S Mode,Windows在该模式下,只能跑MS Store里的软件,不能通过其他方式安装.好处是安全有保障,杜绝一切国产流氓软件.就像iOS一样,APP进商店都需 ...

  7. 迁移桌面程序到MS Store(12)——WPF使用UWP InkToolbar和InkCanvas

    我们在<迁移桌面程序到MS Store(4)——桌面程序调用Win10 API>提到了对Win10 API的调用,但仍存在无法在WPF中使用UWP控件的问题,虽然都是XAML控件,但却是两 ...

  8. 迁移桌面程序到MS Store(13)——动态检查Win10 API是否可用

    假设我们现有一个WPF程序,需要支持1903以前的Windows 10版本.同时在1903以后的版本上,额外多出一个Ink的功能.那么我们就可以通过ApiInformation.IsApiContra ...

  9. 迁移桌面程序到MS Store(2)——Desktop App Converter

    迁移传统桌面程序到MS Store的另一种方式是使用Desktop App Converter工具.虽然本篇标题包含了Desktop App Converter(以下简称DAC),实际上我是来劝你别用 ...

  10. 迁移桌面程序到MS Store(3)——开机自启动

    迁移桌面程序的时候,有可能你会遇到这么个需求——开机自启动.Windows传统桌面程序的传统陋习.不论什么奇葩软件都想要开机自启动,默认就给你打开,一开机哐哐哐什么雷,什么企鹅都蹦出来,也不管你用不用 ...

随机推荐

  1. C#调用开源图像识别类库tessnet2

    首先下载tessnet2_32.dll及相关语言包,将dll加入引用 private tessnet2.Tesseract ocr = new tessnet2.Tesseract();//声明一个O ...

  2. python代码检索小引擎

    https://www.programcreek.com/python/

  3. 【转】先说IEnumerable,我们每天用的foreach你真的懂它吗?

    [转]先说IEnumerable,我们每天用的foreach你真的懂它吗? 我们先思考几个问题: 为什么在foreach中不能修改item的值? 要实现foreach需要满足什么条件? 为什么Linq ...

  4. 导入mysql报错问题

    今天数据导入报错:Got a packet bigger than‘max_allowed_packet’bytes的问题 2个解决方法: 1.临时修改:mysql>set global max ...

  5. python学习 day15 (3月20日)----time

    # '2019-03-20 10:40:00'#这个时间向后推一个月 f1 = time.strptime('2019-03-20 10:40','%Y-%m-%d %H:%M') # 把字符串时间转 ...

  6. Linux+Apache+Mysql+PHP优化技巧

    LAMP 平台由四个组件组成,呈分层结构.每一层都提供了整个软件栈的一个关键部分:Linux.Apache.MySQL.PHP. LAMP这个词的由来最早始于德国杂志“c't Magazine”,Mi ...

  7. matlab 向量场线积分

    syms t x y z F x=cos(t); y=sin(t); z=*sin(t)^-; F=[x^*y , (/)*x^,x*y ] ; %场函数 V=[diff(x,t),diff(y,t) ...

  8. understand试用笔记一阅读VS2010项目

    一.查看vs2010项目 打开understand,File—New—Project...—Next—Next [向导第三步,选“Import Visual Sudio project files”] ...

  9. vue中moudles的作用及使用方法

    1.作用:vuex允许把store分割为模块,每一个模块都有自己的state,actions,getters,mutations甚至是嵌套一些子模块,从上到下进行同样方式的分割 在文件src中创建一个 ...

  10. linux将80端口映射到指定端口命令

    1.添加一个端口映射 将80端口映射到8088端口命令如下: iptables -t nat -I PREROUTING -p tcp --dport 80-j REDIRECT --to-port ...