You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C#实现Windows非系统用户应用程序的获取与关闭?

获取Windows非系统用户应用进程的C#实现方法

要筛选出Word、FoxitReader这类用户级应用进程,核心是区分系统进程和用户交互进程,可以从「窗口存在性」「进程路径」「进程所有者」三个维度组合判断,以下是具体实现方案:

基础过滤方案(适合多数考试场景)

通过筛选有主窗口的进程,并排除系统目录下的进程,快速定位用户应用:

using System.Diagnostics;
using System.IO;
using System.Linq;

List<Process> GetUserApplications()
{
    var userApps = new List<Process>();
    // 定义系统进程常见路径
    var systemDirs = new[]
    {
        Environment.GetFolderPath(Environment.SpecialFolder.Windows),
        Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "System32"),
        Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "SysWOW64")
    };

    foreach (var process in Process.GetProcesses())
    {
        try
        {
            // 跳过无主窗口的进程(多数系统进程/后台服务无窗口)
            if (process.MainWindowHandle == IntPtr.Zero)
                continue;

            // 获取进程文件路径,跳过无权限访问的进程
            var procPath = process.MainModule.FileName;
            // 判断进程是否位于系统目录
            bool isSystemProc = systemDirs.Any(dir => procPath.StartsWith(dir, StringComparison.OrdinalIgnoreCase));
            
            if (!isSystemProc)
                userApps.Add(process);
        }
        catch
        {
            // 捕获权限异常,跳过无法访问的系统核心进程
            continue;
        }
    }
    return userApps;
}

方案说明

  • 优点:实现简单,性能开销小,能覆盖绝大多数带UI的用户应用。
  • 局限性:会漏掉无窗口的用户后台进程,部分进程因权限问题无法获取路径。

进阶精确过滤方案

通过判断进程的所有者账户,进一步排除系统账户运行的进程,过滤更精准:

首先需要引入P/Invoke代码获取进程所有者:

using System.Security.Principal;
using System.Runtime.InteropServices;

[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool OpenProcessToken(IntPtr ProcessHandle, uint DesiredAccess, out IntPtr TokenHandle);

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr hObject);

// 获取进程的所有者身份
private static WindowsIdentity GetProcessOwner(Process process)
{
    IntPtr tokenHandle = IntPtr.Zero;
    try
    {
        // 申请查询进程令牌的权限
        if (!OpenProcessToken(process.Handle, 0x0008 /* TOKEN_QUERY */, out tokenHandle))
            return null;
        
        return new WindowsIdentity(tokenHandle);
    }
    catch
    {
        return null;
    }
    finally
    {
        // 释放令牌句柄
        if (tokenHandle != IntPtr.Zero)
            CloseHandle(tokenHandle);
    }
}

// 判断是否为系统内置账户
private static bool IsSystemAccount(SecurityIdentifier sid)
{
    return sid.IsWellKnown(WellKnownSidType.LocalSystemSid) ||
           sid.IsWellKnown(WellKnownSidType.NetworkServiceSid) ||
           sid.IsWellKnown(WellKnownSidType.LocalServiceSid);
}

然后修改筛选方法,加入所有者判断:

List<Process> GetUserApplications()
{
    var userApps = new List<Process>();
    var systemDirs = new[]
    {
        Environment.GetFolderPath(Environment.SpecialFolder.Windows),
        Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "System32"),
        Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "SysWOW64")
    };
    var currentUserSid = WindowsIdentity.GetCurrent().User.Value;

    foreach (var process in Process.GetProcesses())
    {
        try
        {
            if (process.MainWindowHandle == IntPtr.Zero)
                continue;

            var procPath = process.MainModule.FileName;
            bool isSystemPath = systemDirs.Any(dir => procPath.StartsWith(dir, StringComparison.OrdinalIgnoreCase));
            if (isSystemPath)
                continue;

            // 获取进程所有者,排除系统账户
            var owner = GetProcessOwner(process);
            if (owner == null || !IsSystemAccount(owner.User))
                userApps.Add(process);
        }
        catch
        {
            continue;
        }
    }
    return userApps;
}

方案说明

  • 优点:结合路径和账户双重判断,能排除系统账户运行的非系统目录进程,过滤更准确。
  • 注意:需要以管理员权限运行程序,否则无法获取部分进程的令牌信息。

额外注意事项

  1. 权限要求:程序必须以管理员身份启动,否则无法访问多数系统进程和部分用户进程的信息。
  2. 白名单机制:建议添加白名单,将自己的考试安全程序排除在关闭列表之外,避免误杀。
  3. 友好关闭流程:优先调用Process.CloseMainWindow()发送关闭请求,等待3-5秒后再调用Process.Kill(),减少用户数据丢失风险。
  4. 多进程应用处理:部分用户应用(如Chrome)会启动多个进程,需要遍历所有匹配进程并关闭。

内容的提问来源于stack exchange,提问作者Khaled El Attar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 09:15:36