UWP中Process.GetProcessesByName失效,如何检测TeamSpeak是否运行?
我之前也踩过这个一模一样的坑!WinForm里用Process.GetProcessesByName检测进程顺风顺水,到UWP里直接报平台不支持的错误,核心原因其实很简单——UWP的沙箱安全限制:
默认情况下,UWP应用运行在隔离的沙箱环境中,没有权限枚举系统里的所有进程,System.Diagnostics.Process类的相关API在UWP平台上是被禁用的,这就是你看到Retrieving information about local processes is not supported on this platform报错的原因。
不过别担心,UWP还是有办法实现这个需求的,下面是具体的解决方案:
第一步:添加应用诊断权限
要获取进程信息,首先得给应用开权限。你需要在Package.appxmanifest里添加App Diagnostics权限:
- 直接编辑XML的话,找到
<Capabilities>节点,加入以下代码:
<Capability Name="appDiagnostics" />
- 或者用可视化编辑器:打开
Package.appxmanifest,切换到「功能」选项卡,勾选「应用诊断」。
注意:这个权限需要用户手动授权,应用第一次访问进程信息时会弹出提示,用户也可以在系统设置的「隐私>应用诊断」里手动开启。
第二步:用UWP原生API重写检测逻辑
放弃System.Diagnostics.Process,改用UWP专属的Windows.System.Diagnostics.ProcessDiagnosticInfo类,它能在权限允许的情况下枚举系统进程。重写后的代码如下:
using Windows.System.Diagnostics; using System.Linq; public async Task<bool> IsTSOpenAsync() { try { // 获取所有正在运行的进程(异步操作) var allProcesses = await ProcessDiagnosticInfo.GetForProcessesAsync(); // 检查是否存在TeamSpeak的两个版本进程 bool tsIsRunning = allProcesses.Any(process => process.ExecutableFileName.Equals("ts3client_win64.exe", StringComparison.OrdinalIgnoreCase) || process.ExecutableFileName.Equals("ts3client_win32.exe", StringComparison.OrdinalIgnoreCase)); // 这里注意:你的原代码逻辑好像写反了?原代码是两个进程都为空时返回true, // 如果要和原逻辑保持一致,就返回 !tsIsRunning return tsIsRunning; } catch (UnauthorizedAccessException) { // 用户拒绝了权限,这里可以加个提示或者返回默认值 return false; } }
小提示:
- 这个API是异步的,所以方法要改成
async Task<bool>,调用的时候记得加await - 一定要加异常捕获,防止用户拒绝权限导致崩溃
补充:为什么WinForm能用?
WinForm是传统桌面应用,运行在完全信任的环境里,没有沙箱的权限限制,所以可以随便用System.Diagnostics.Process的API。但UWP为了安全性,对系统资源的访问做了严格管控,必须用官方提供的WinRT API才能实现这类操作。
内容的提问来源于stack exchange,提问作者kurocezone

