C#在Win 7/8/10 OS下删除HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB子项

从Win XP到Win 7/8/10,OS(Operating System)有些安全特性改变了,所以不能向以前Win XP那样直接可以删除Windows Registry中的HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB下面的子项。

我们可以通过以下方法。

  • 生成的exe需要运行在Administrator模式下。这点是关于UAC(User Control Access)
  • 删除HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB时,通过PsExec.exe需要把权限提升到SYSTEM等级。

以下详细介绍这两点。


  • UAC

我们生成exe时,需要exe运行在Administrator控制下。

右击项目名,点击“属性”项,进入“安全性”选项页,选择“启用ClickOnce安全设置”。


这样会自动生成app.manifest,并把其中“requestedExecutionLevel”改成“requiredAdministrator”。


再次取消“启用ClickOnce安全设置”的勾选



  • PsExec

示例有三个exe文件

DeleteUsbRegKey.exe: 实现删除注册表

DeleteUsbRegKeyWrapper.exe: 调用PsExec.exe来运行DeleteUsbRegKey.exe

PsExec.exe

直接上代码


  • DeleteUsbRegKey.exe

namespace DeleteUsbRegKey
{
    public class UsbRegistryOperator : IUsbRegistryOperator
    {
        private const string UsbRootKeyPath = @"SYSTEM\CurrentControlSet\Enum\USB";
 
        public bool Exists(string usbKeyName)
        {
            using (var localMachineKey = Registry.LocalMachine)
            {
                using (var usbRootKey = localMachineKey.OpenSubKey(UsbRootKeyPath))
                {
                    return usbRootKey
                            .GetSubKeyNames()
                            .Any(name => name.ToUpper() == usbKeyName.ToUpper());
                }
            }
        }
 
        public void DeleteSubKeys(string usbKeyName)
        {
            if (!Exists(usbKeyName))
                return;
 
            using (var localMachineKey = Registry.LocalMachine)
            {
                var usbKeyPath = UsbRootKeyPath + @"\" + usbKeyName;
                using (var usbKey = localMachineKey.OpenSubKey(usbKeyPath, RegistryKeyPermissionCheck.ReadWriteSubTree))
                {
                    foreach (var name in usbKey.GetSubKeyNames())
                    {
                        usbKey.DeleteSubKeyTree(name);
                    }
                }
            }
        }
    }
}


namespace DeleteUsbRegKey
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                if (!args.Any())
                    throw new ArgumentException("Should have 1 argument at least");
 
                var deleter = BuildUsbKeyDeleter();
                var usbKeyName = args[0];
                deleter.DeleteSubKeys(usbKeyName);
            }
            catch (Exception exception)
            {
                Console.WriteLine("Message:\n" + exception.Message);
                Console.WriteLine();
                Console.WriteLine("StackTrace:\n" + exception.StackTrace);
            }
        }
 
        private static IUsbKeyDeleter BuildUsbKeyDeleter()
        {
            var usbRegistryOperator = new UsbRegistryOperator();
            return new UsbKeyDeleter(usbRegistryOperator);
        }
    }
}

  • DeleteUsbRegKeyWrapper.exe

namespace DeleteUsbRegKeyWrapper
{
    public class PathsProvider : IPathsProvider
    {
        public string GetDirectory()
        {
            return AppDomain.CurrentDomain.BaseDirectory;
        }
 
        public string GetDeleteUsbRegKeyPath()
        {
            const string fileName = "DeleteUsbRegKey.exe";
            return Path.Combine(GetDirectory(), fileName);
        }
 
        public string GetPsExecPath()
        {
            const string fileName = "PsExec.exe";
            return Path.Combine(GetDirectory(), fileName);
        }
    }
}


namespace DeleteUsbRegKeyWrapper
{
    public class PsExecStarter : IPsExecStarter
    {
        private readonly IPathsProvider _pathsProvider;
 
        public PsExecStarter(IPathsProvider pathsProvider)
        {
            _pathsProvider = pathsProvider;
        }
 
        public void Run(string usbKeyName)
        {
            var psi = new ProcessStartInfo
            {
                FileName = _pathsProvider.GetPsExecPath(),
                Arguments = BuildArguments(usbKeyName),
                WorkingDirectory = _pathsProvider.GetDirectory()
            };
 
            var process = Process.Start(psi);
 
            process.WaitForExit();
        }
 
        private string BuildArguments(string usbKeyName)
        {
            return string.Format("-i -s \"{0}\" \"{1}\"",
                _pathsProvider.GetDeleteUsbRegKeyPath(), usbKeyName);
        }
    }
}


namespace DeleteUsbRegKeyWrapper
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                if (!args.Any())
                    throw new ArgumentException("Should have 1 argument at least");
 
                var starter = BuildPsExecStarter();
                var usbKeyName = args[0];
                starter.Run(usbKeyName);
            }
            catch (Exception exception)
            {
                Console.WriteLine("Message:\n" + exception.Message);
                Console.WriteLine();
                Console.WriteLine("StackTrace:\n" + exception.StackTrace);
            }
        }
 
        private static IPsExecStarter BuildPsExecStarter()
        {
            var pathsProvider = new PathsProvider();
            return new PsExecStarter(pathsProvider);
        }
    }
}



这样即使“Everyone”没有“Full Control”也是可以删除HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB下面的子项的。