是否存在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
相关产品推荐
相关产品推荐

