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

是否存在Microsoft API可查询Windows启动应用的启用状态与影响级别?

获取Windows启动应用(含状态与影响级别)的C#实现

Windows设置里Settings->Apps->Startup显示的启动项包含传统Win32应用启动项和UWP应用启动项两类,传统的Win32_StartupCommand或wmic命令只能读取部分Win32启动项,无法获取启用/禁用状态、影响级别以及UWP启动项。以下是纯C#的实现方案:

一、核心逻辑说明

  • 传统Win32启动项存储在注册表的Run路径下,启用/禁用状态对应StartupApproved注册表项的二进制值
  • UWP启动项的信息通过Windows Runtime API获取,状态和影响级别可通过StartupTask接口及对应注册表项读取

二、代码实现

1. 定义启动项模型

// 传统Win32启动项模型
public class Win32StartupItem
{
    public string Name { get; set; }
    public string Command { get; set; }
    public bool IsEnabled { get; set; }
    public string Location { get; set; }
    public string User { get; set; }
}

// UWP启动项模型
public class UwpStartupItem
{
    public string AppName { get; set; }
    public string PackageFamilyName { get; set; }
    public bool IsEnabled { get; set; }
    public string ImpactLevel { get; set; } // 对应High/Medium/Low/Unknown
}

2. 读取传统Win32启动项

using Microsoft.Win32;
using System;
using System.Collections.Generic;

public static class Win32StartupManager
{
    // 获取当前用户的Win32启动项
    public static List<Win32StartupItem> GetCurrentUserItems()
    {
        var items = new List<Win32StartupItem>();
        using var runKey = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", false);
        if (runKey == null) return items;

        foreach (var name in runKey.GetValueNames())
        {
            items.Add(new Win32StartupItem
            {
                Name = name,
                Command = runKey.GetValue(name)?.ToString(),
                IsEnabled = IsItemEnabled(name, Registry.CurrentUser),
                Location = "Current User Run",
                User = Environment.UserName
            });
        }
        return items;
    }

    // 获取全局(所有用户)的Win32启动项
    public static List<Win32StartupItem> GetLocalMachineItems()
    {
        var items = new List<Win32StartupItem>();
        using var runKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", false);
        if (runKey == null) return items;

        foreach (var name in runKey.GetValueNames())
        {
            items.Add(new Win32StartupItem
            {
                Name = name,
                Command = runKey.GetValue(name)?.ToString(),
                IsEnabled = IsItemEnabled(name, Registry.LocalMachine),
                Location = "Local Machine Run",
                User = "All Users"
            });
        }
        return items;
    }

    // 判断启动项是否启用:00 00 00 00=启用,01 00 00 00=禁用
    private static bool IsItemEnabled(string itemName, RegistryKey rootKey)
    {
        using var approvedKey = rootKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run", false);
        if (approvedKey == null) return true; // 无状态记录默认视为启用

        var statusBytes = approvedKey.GetValue(itemName) as byte[];
        return statusBytes != null && statusBytes.Length >= 4 && statusBytes[0] == 0x00;
    }
}

3. 读取UWP启动项

需在.NET Core/.NET 5+项目中添加对Windows Runtime的引用,或在桌面应用中启用WinRT支持:

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.Management.Deployment;
using Microsoft.Win32;

public static class UwpStartupManager
{
    public static async Task<List<UwpStartupItem>> GetItemsAsync()
    {
        var items = new List<UwpStartupItem>();
        var packageManager = new PackageManager();
        var allPackages = packageManager.FindPackagesForUser(string.Empty);

        foreach (var package in allPackages)
        {
            try
            {
                var appEntries = await package.GetAppListEntriesAsync();
                foreach (var entry in appEntries)
                {
                    var startupTask = await StartupTask.GetAsync(entry.AppUserModelId);
                    if (startupTask == null) continue;

                    items.Add(new UwpStartupItem
                    {
                        AppName = entry.DisplayInfo.DisplayName,
                        PackageFamilyName = package.Id.FamilyName,
                        IsEnabled = startupTask.State == StartupTaskState.Enabled,
                        ImpactLevel = GetImpactLevel(startupTask.Id)
                    });
                }
            }
            catch
            {
                // 跳过无权限或无效的包
                continue;
            }
        }
        return items;
    }

    // 从注册表读取影响级别:3=High,2=Medium,1=Low
    private static string GetImpactLevel(string startupTaskId)
    {
        using var key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\StartupApps\" + startupTaskId, false);
        if (key == null) return "Unknown";

        return key.GetValue("Impact")?.ToString() switch
        {
            "3" => "High",
            "2" => "Medium",
            "1" => "Low",
            _ => "Unknown"
        };
    }
}

4. 整合所有启动项

public static async Task<List<object>> GetAllStartupItemsAsync()
{
    var allItems = new List<object>();
    allItems.AddRange(Win32StartupManager.GetCurrentUserItems());
    allItems.AddRange(Win32StartupManager.GetLocalMachineItems());
    allItems.AddRange(await UwpStartupManager.GetItemsAsync());
    return allItems;
}

三、注意事项

  • 读取全局注册表项和UWP启动项需要管理员权限,否则可能返回不完整数据
  • UWP启动项读取需应用声明packageQuery权限,可在项目清单中配置
  • 部分应用的影响级别可能无注册表记录,此时返回Unknown为正常情况

内容的提问来源于stack exchange,提问作者ktryan88

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 11:50:30