返回

无界面启动UWP应用: 后台运行方案详解

windows

后台启动 UWP 应用

开发中,有时需要UWP(通用Windows平台)应用程序在后台运行,而无需显示用户界面。 这项需求在多种场景下出现,例如在桌面应用程序中调用UWP的特定功能,同时避免干扰用户。 本文探讨如何在不显示窗口的情况下启动UWP应用,并提供一些实现方案。

问题根源

直接通过通常方式启动 UWP 应用时,其默认行为是显示主窗口。但某些情况下,像文中提到的屏幕投影,应用程序窗口的存在实际上是多余的,或者说影响用户体验。 UWP 的特定 API 例如 ProjectionManager.StartProjectingAsync 要求 ApplicationView 实例作为参数, 这个实例代表了应用的一个可见窗口视图,所以,简单隐藏窗口的方式不可行。根本问题在于 UWP 应用生命周期的设计与图形界面的强耦合性,应用默认要进行显示操作。

解决方案一:启动但不激活

可以利用 Windows 进程启动 API ,先启动应用,但不使其窗口激活,处于“暂停”或者后台状态,然后再调用其相应的函数。这个方式不是完美的隐藏,因为窗口在某些情况下会被操作系统拉起来或者短暂出现,但依然能有效达到应用隐式运行的目的。

步骤:

  1. 使用explorer.exe 启动 UWP 应用: 通过 shell 命令启动应用程序,添加 !NoActivate 参数指示不激活应用程序窗口。
  2. 通过 COM 调用或 APP SERVICE 连接: 启动后,桌面应用程序可以使用 APP SERVICE 或其他进程间通信方式(如COM接口)与 UWP 应用程序交互。

代码示例(命令行):

explorer.exe shell:appsfolder\your_package_name!App!NoActivate

其中 your_package_name 为 UWP 应用的包名, !App 为入口点的应用名,可以在应用的 manifest 文件中找到。!NoActivate 参数会阻止窗口变为前台活动状态。

注意: 需要管理员权限或者UWP应用本身的后台任务权限,确保这个方式能正常执行。

解决方案二:扩展激活 (Extension Activation)

通过扩展激活机制, UWP 应用可以在后台进程中执行代码。通过此机制,UWP 应用程序不一定必须呈现窗口。该方法通常使用特定的启动方式,并且处理特定事件来实现。

步骤:

  1. 定义扩展: 在 UWP 应用的 Package.appxmanifest 中,定义一个扩展点,以便应用程序能够在特定事件发生时启动。比如定义一个 App Service 。
  2. 启动扩展: 当需要执行 UWP 代码时,使用指定的方式来触发此扩展。桌面程序可以通过指定的通信协议 (例如 App Service) 来调用扩展。

代码示例 (UWP 应用的 Package.appxmanifest ) :

  <Application>
    <Extensions>
       <uap:Extension Category="windows.appService" EntryPoint="YourNameSpace.BackgroundServiceTask">
          <uap:AppService Name="com.YourCompany.YourAppService"/>
        </uap:Extension>
     </Extensions>
  </Application>

YourNameSpace.BackgroundServiceTask 是你在 UWP 应用中创建的后台任务,处理具体逻辑。 com.YourCompany.YourAppService是 AppService 的唯一标识符。
代码示例(WPF 调用 AppService):

// AppService 调用
 var connection = new AppServiceConnection
        {
             AppServiceName = "com.YourCompany.YourAppService",
             PackageFamilyName = "Your_UWP_PackageFamilyName"
        };
    AppServiceConnectionStatus status = await connection.OpenAsync();
    if (status == AppServiceConnectionStatus.Success)
     {
       var inputs = new ValueSet();
       inputs["command"] = "startProjection"; //可以定义 UWP 应用要执行的动作指令
      var response = await connection.SendMessageAsync(inputs);
      if (response.Status == AppServiceResponseStatus.Success) {
             //处理来自UWP的返回值
      }
    }

Your_UWP_PackageFamilyName可以在应用包的属性里获取,用于精准启动 App Service。

优点: 这个方法可以真正实现UWP应用后台无UI执行,且资源占用相对较少。 适合需要UWP 应用后台提供计算或处理能力的场景。
注意事项: 使用扩展激活方案,要特别注意处理应用的生命周期,并保证扩展在正确的进程内执行。 AppService 使用较为简单,并且是可靠的一种选择。

额外建议

  • 错误处理: 必须妥善处理可能出现的错误情况, 例如启动失败或通信错误,以便确保应用稳健性。
  • 安全性: 对进程间的通信内容进行适当的加密和验证,防止数据泄露。对于跨越用户隔离的通信,比如 App Service, 要确保目标 UWP 应用是被正确配置并且是可信任的。
  • 资源管理: 即使应用在后台运行,也要注意内存和 CPU 资源消耗,确保其行为不会影响用户系统。

希望以上分析和解决方案能为你提供帮助。 实际选择取决于具体需求以及对 UWP 生命周期和后台处理的掌握程度。 理解 UWP 的运作方式有助于找到更适合的方案。