zoukankan      html  css  js  c++  java
  • 迁移桌面程序到MS Store(14)——APPX嵌入WCF Service以Admin权限运行

    Windows10 1809版本开始,微软又对UWP开放了新的Capability:AllowElevation。 通过这个新的Capability,UWP APP能够在运行时向用户请求Admin权限,配合Windows 1607版本就引入的RunFullTrust Capability(参考《迁移桌面程序到MS Store(9)——APPX With Desktop Extension 》),我们可以让MS Store中的APP拥有无限接近传统桌面程序的能力。
    本篇提到的Sample工程位于全球最大的同性交友平台GitHub:
    https://github.com/manupstairs/UWPAllowElevation

    上图解释了整个程序运行的流程,UWP APP通过RunFullTrust Capability来运行一个exe程序,在这个exe程序中,又因为新的AllowElevation而能够请求Admin权限来启动WCF Servcie。用户在UAC弹窗中确认授予Admin权限后,我们就在UWP APP的身后拥有了一个具有Admin权限的WCF Service。
    首先让我们创建WCFBackgroundProcess工程,包含一个Hello World级别的WCF Service。在该服务的接口中,我们定义了三个方法,用来启动,停止和查询Windows Service状态。这么设计是因为这些操作需要Admin权限。

        [ServiceContract]
        public interface ILocalService
        {
    
            [OperationContract]
            ServiceControllerStatus StartService(string name);
    
            [OperationContract]
            ServiceControllerStatus StopService(string name);
    
            [OperationContract]
            ServiceControllerStatus GetServiceStatus(string name);
        }

    WCFBackgroundProcess工程本身是一个Console类型的程序,作为exe启动后,我们就可以在UWP Client工程中,添加对WCFBackgroundProcess中服务的引用。具体可以参考《迁移桌面程序到MS Store(7)——APPX + Service》。

        class Program
        {
            static void Main(string[] args)
            {
                var selfHost = new ServiceHost(typeof(LocalServiceWrapper));
    
                selfHost.Open();
    
                Console.WriteLine("The service is ready.");
    
                // Close the ServiceHost to stop the service.
                Console.WriteLine("Press <Enter> to terminate the service.");
                Console.WriteLine();
                Console.ReadLine();
                selfHost.Close();
            }
        }

    Launcher工程是一个标准的Console程序,内容非常简单,通过ProcessStartInfo类来启动WCFBackgroundProcess.exe。该工程在UWP环境下所需的AllowElevation我们在创建Packaging工程时会添加。

        class Program
        {
            static void Main(string[] args)
            {
                string result = Assembly.GetExecutingAssembly().Location;
                int index = result.LastIndexOf("\");
                string rootPath = $"{result.Substring(0, index)}\..\";
    
                rootPath += @"WCFBackgroundProcessWCFBackgroundProcess.exe";
    
                ProcessStartInfo info = new ProcessStartInfo
                {
                    Verb = "runas",
                    UseShellExecute = true,
                    FileName = rootPath
                };
                Process.Start(info);
            }
        }

    接着创建UWPClient工程,这是一个标准的UWP项目。除了WCFBackgroundService的引用外,我们还需要通过NuGet添加Windows Desktop Extension for the UWP来实现对Launcher.exe的调用(参考《迁移桌面程序到MS Store(9)——APPX With Desktop Extension 》)。

     

    UWPClient仅包含唯一的MainPage,四个按钮事件分别负责启动Launcher.exe,启动、停止、查询BluetoothService的状态,代码如下:

        public sealed partial class MainPage : Page
        {
            private string serviceName = "bthserv";
            private LocalServiceClient client = new LocalServiceClient();
    
            public MainPage()
            {
                this.InitializeComponent();
            }
    
            private async void StopButton_Click(object sender, RoutedEventArgs e)
            {
                var status = await client.StopServiceAsync(serviceName);
                textBlockStatus.Text = status.ToString();
            }
    
            private async void StartButton_Click(object sender, RoutedEventArgs e)
            {
                var status = await client.StartServiceAsync(serviceName);
                textBlockStatus.Text = status.ToString();
            }
    
            private async void QueryButton_Click(object sender, RoutedEventArgs e)
            {
                var status = await client.GetServiceStatusAsync(serviceName);
                textBlockStatus.Text = status.ToString();
            }
    
            private async void RunWCFService_Click(object sender, RoutedEventArgs e)
            {
                if (ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0))
                {
                    await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync();
                }
            }
        }

    以上就是所有的准备工作。然后我们创建作为启动项目的AllowElevationPackaging工程(参考《迁移桌面程序到MS Store(1)——通过Visual Studio创建Packaging工程》)。在AllowElevationPackaging的Applications中包含之前创建的所有三个工程,同时将UWPClient设为Entry Point。

    右键选中Package.aapxmanifest后进行编辑,在<Application/>节点中添加:

          <Extensions>
            <desktop:Extension xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10" Category="windows.fullTrustProcess" Executable="LauncherLauncher.exe" />
          </Extensions>

    同时修改Capabilities节点:

      <Capabilities>
        <Capability Name="internetClient" />
        <rescap:Capability Name="runFullTrust" />
        <rescap:Capability Name="allowElevation" />
      </Capabilities>

    完成后保存关闭文件,大功告成!编译整个解决方案确保没有任何错误,然后让我们点击F5开始运行(记得将AllowElevationPackaging设为启动项)。
    首先我们先点击Apply for Elevation capability and Run WCF Service按钮。在UAC窗口中我们同意给予Admin权限,WCF Service顺利启动。感兴趣的同学可以通过窗口的标题栏查看WCFBackgroundProcess.exe的物理路径。

    然后我们即可以开始查询蓝牙服务的运行状态了。如果用的是蓝牙鼠标,在点击Stop Blue Support Service的同时不要惊慌失措哦。本篇作为《迁移桌面程序到MS Store》系列的最终篇,没人看的系列就准备太监了。犹豫就会败北,果断就会白给。后续博客将专注于.NET Core的学习,与诸君共勉!

    GitHub:
    https://github.com/manupstairs/UWPAllowElevation

  • 相关阅读:
    Linux下NDK编译FFMPEG包含neon参数
    编译器优化陷阱——全局指针多次使用异常
    Linux下使用NDK编译FFMPEG(libstagefright)
    查看Android支持的硬解码信息
    图片格式转换
    转 MFC 主界面函数中线程等待避免界面卡死的处理方法
    Windows Shell编程实现重叠图标IconOverlay
    转 MFC中 GB2312、UTF-8、unicode 之间转换
    windows双机调试
    位图BITMAP结构
  • 原文地址:https://www.cnblogs.com/manupstairs/p/12370804.html
Copyright © 2011-2022 走看看