如何在UWP应用中通过FullTrustLauncher终止已启动的.exe文件?
UWP场景下终止FullTrustLauncher拉起的exe进程的实现方案
核心前提
FullTrustLauncher的原生API(如LaunchFullTrustProcessForAppAsync)本身不会返回被拉起的Win32进程的PID或句柄,同时UWP沙箱的默认权限不允许跨边界直接操作其他Win32进程,因此所有终止逻辑必须依托同包的信任边界设计,不能依靠全局系统进程枚举进行盲操作。
方案1:AppService通信实现优雅终止(推荐)
该方案兼容性覆盖所有支持FullTrustLauncher的Windows版本,安全性最高,不会出现误杀或进程数据丢失问题。
- 改造目标FullTrust exe(即被你通过FullTrustLauncher拉起的非沙箱程序):在程序启动入口主动连接当前UWP包下预先注册的AppService端点,建立双向通信通道。因为是同包内的进程交互,不需要额外申请特殊系统权限。
- UWP端在AppService的连接回调中,校验连接来源的包族名与自身一致后,保存这个连接的持久引用。当需要终止目标exe时,通过该连接发送自定义的退出指令。
- 目标FullTrust exe收到退出指令后,优先完成临时数据保存、持有资源释放的逻辑,再执行正常退出流程,避免强制终止带来的异常。
对应的核心实现代码参考:
// UWP端AppService处理逻辑(写在App.xaml.cs的后台激活入口) private AppServiceConnection _activeFullTrustConnection; protected override async void OnBackgroundActivated(BackgroundActivatedEventArgs args) { var deferral = args.TaskInstance.GetDeferral(); if (args.TaskInstance.TriggerDetails is AppServiceTriggerDetails details) { // 仅接受同包FullTrust进程的连接 if (details.CallerPackageFamilyName == Package.Current.Id.FamilyName) { _activeFullTrustConnection = details.AppServiceConnection; // 需要终止时,向目标进程发送优雅退出指令 var exitCommand = new ValueSet { ["command"] = "graceful_exit" }; await _activeFullTrustConnection.SendMessageAsync(exitCommand); } } deferral.Complete(); }
// FullTrust exe端的消息接收逻辑 private async void OnServiceMessageReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args) { var deferral = args.Request.GetDeferral(); if (args.Request.Message["command"]?.ToString() == "graceful_exit") { // 在此处完成资源释放、数据保存逻辑 Application.Current.Shutdown(); Environment.Exit(0); } deferral.Complete(); }
方案2:同包进程API实现强制终止
该方案适配Windows 10 1903及以上版本,不需要改造现有exe的通信逻辑,适合对进程退出优雅度要求不高的场景。
- 启动目标exe时,通过FullTrustLauncher的传参通道,向exe的命令行传入一个唯一的实例标识(如随机生成的Guid),用于后续精准定位目标进程。
- 终止操作触发时,调用
Package.Current.GetAppListEntriesAsync()获取当前包关联的所有应用入口,再通过每个入口的GetAppProcessesAsync()方法拿到所有当前运行的同包FullTrust进程。 - 遍历所有进程的命令行参数,匹配之前传入的唯一实例标识,定位到目标进程后直接调用
Kill()方法完成终止。
对应的核心实现代码参考:
// 精准匹配并终止目标FullTrust进程 var packageEntries = await Package.Current.GetAppListEntriesAsync(); foreach (var entry in packageEntries) { var runningProcesses = await entry.GetAppProcessesAsync(); foreach (var process in runningProcesses) { // 匹配启动时写入的唯一实例参数,避免误杀 if (process.CommandLine.Contains($"instanceId={_launchedInstanceId}")) { process.Kill(); } } }
常见踩坑提示
- 禁止通过系统全局进程列表按exe文件名匹配杀进程:用户可能手动打开了和目标exe同名的其他程序,这种盲匹配会直接误杀用户的正常进程,是生产环境的高频故障点。
- FullTrust进程具备独立生命周期:通过FullTrustLauncher拉起的exe是独立运行的Win32进程,不会随着UWP主窗口的关闭自动退出,必须主动实现终止逻辑,否则会出现后台进程残留占用系统资源的问题。
- 版本兼容性注意:基于包入口遍历运行中进程的API是Windows 10 1903(版本18362)之后才提供的,如果应用需要支持更早的系统版本,必须采用AppService通信的实现方案。
内容的提问来源于stack exchange,提问作者Hana Munamana
相关产品推荐
相关产品推荐

