本篇咱們以一個Sample工程,來講明如何把一個常見結構的desktop application,轉製成APPX並在MS Store提供下載。前端
以前的篇章中,咱們已經介紹了一些內容,包括如何經過Visual Studio建立Packaging工程, 如何將Class Libraries轉換到.NET Standard版本。至此,UI界面,以及部分DLL的遷移問題獲得解決。但有時候咱們的desktop application還包括一個本地的Background Service。那麼目前微軟推薦的策略,依然是經過建立一個WCF服務,而後host在Windows Service上,來提供給前端的APPX訪問。git
可能有同窗要問,爲何咱們須要Windows Service。這是由於在前臺程序中,通常不會要求admin權限,這在企業級軟件中是較爲常見的需求,用PowerPiont的普通員工,一般被認爲即沒有power也沒有point,更不須要admin權限……(悲劇啊T_T)但咱們能夠把須要admin權限,訪問硬件等相關操做,放到Service中,由IT統一部署到機器上,避免了沒有admin權限沒法正常運行程序的問題。github
在接下來的Sample中,咱們試圖經過代碼啓動一個Windows服務"aspnet_state"。這個工程很是的簡單,咱們要作的僅僅是在UWP project中調用一下Windonws Service上運行的WCF服務。工程結構以下圖。由於工程主要想說明UI程序對WCF服務的引用,因此請不要在乎使用UI程序是UWP仍是WPF。實際使用中,對於Desktop Bridge的程序,非WCF的其餘Background Service也是能夠的,好比Named Pipes等。windows
咱們的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權限。app
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(5)); } 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。async
第二種更爲純粹,由UWP+.NET Standard+WCF組成,相應也須要更多的改動,而Native C++ Libraries的部分則須要下沉到Service中。這種的好處在於遷移的更爲完全,對將來有着更好的適應。固然哪天某軟翻臉不認帳,拋棄UWP又回頭去搞.NET Core的WPF的話,你就當我沒說過……ide
本篇討論瞭如何將現有的desktop application,在維持已有架構的前提下,轉製成APPX放到MS Store提供下載。
固然大家會以爲多出來的Service部分簡直不能忍。後續我會進一步介紹如何處理Service部分,不至於讓強迫症患者在評論裏罵我……
本篇Sample工程的GitHub連接:
https://github.com/manupstairs/UWPWithWCFSample學習