首页 > 其他分享 >.NET使用P/Invoke来实现注册表的增、删、改、查功能

.NET使用P/Invoke来实现注册表的增、删、改、查功能

时间:2024-05-14 18:09:34浏览次数:22  
标签:IntPtr string Invoke int hKey RegistryRoot 注册表 NET

注册表可以用来进行存储一些程序的信息,例如用户的权限、或者某些值等,可以根据个人需要进行存储和删减。

当前注册表主目录:

引用包 Wesky.Net.OpenTools 1.0.5或者以上版本

 操作演示:

创建注册表项

设置注册表值

读取注册表值

删除注册表值

删除注册表项

操作演示代码

IRegistryManager registryManager = new RegistryManager();

// 创建注册表项
// registryManager.CreateKey(RegistryRoot.CurrentUser, @"Wesky\MyApp");

// 设置注册表值
// registryManager.SetValue(RegistryRoot.CurrentUser, @"Wesky\MyApp", "MyValue", "Hello, Registry!");

// 读取注册表值
// var value = registryManager.GetValue(RegistryRoot.CurrentUser, @"Wesky\MyApp", "MyValue");
// Console.WriteLine($"读取到的注册表值:{value}");

// 删除注册表值
// registryManager.DeleteValue(RegistryRoot.CurrentUser, @"Wesky\MyApp", "MyValue");

// 删除注册表项
registryManager.DeleteKey(RegistryRoot.CurrentUser, @"Wesky\MyApp");
Console.WriteLine("Over");
Console.ReadKey();

 

 

核心包内源码:

 [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
    private static extern int RegCreateKeyEx(
        IntPtr hKey,
        string lpSubKey,
        int Reserved,
        string lpClass,
        int dwOptions,
        int samDesired,
        IntPtr lpSecurityAttributes,
        out IntPtr phkResult,
        out int lpdwDisposition);

    [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
    private static extern int RegOpenKeyEx(
        IntPtr hKey,
        string lpSubKey,
        int ulOptions,
        int samDesired,
        out IntPtr phkResult);

    [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
    private static extern int RegCloseKey(IntPtr hKey);

    [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
    private static extern int RegSetValueEx(
        IntPtr hKey,
        string lpValueName,
        int Reserved,
        int dwType,
        byte[] lpData,
        int cbData);

    [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
    private static extern int RegGetValue(
        IntPtr hKey,
        string lpSubKey,
        string lpValue,
        int dwFlags,
        out int pdwType,
        StringBuilder pvData,
        ref int pcbData);

    [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
    private static extern int RegDeleteKey(IntPtr hKey, string lpSubKey);

    [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
    private static extern int RegDeleteValue(IntPtr hKey, string lpValueName);

    /// <summary>
    /// 获取注册表根键
    /// Get registry root key
    /// </summary>
    /// <param name="root"></param>
    /// <returns></returns>
    /// <exception cref="ArgumentOutOfRangeException"></exception>
    private IntPtr GetRegistryRootKey(RegistryRoot root)
    {
        switch (root)
        {
            case RegistryRoot.ClassesRoot:
                return HKEY_CLASSES_ROOT;
            case RegistryRoot.CurrentUser:
                return HKEY_CURRENT_USER;
            case RegistryRoot.LocalMachine:
                return HKEY_LOCAL_MACHINE;
            case RegistryRoot.Users:
                return HKEY_USERS;
            case RegistryRoot.CurrentConfig:
                return HKEY_CURRENT_CONFIG;
            default:
                throw new ArgumentOutOfRangeException(nameof(root), root, null);
        }
    }

    /// <summary>
    /// 创建注册表键
    /// Create registry key
    /// </summary>
    /// <param name="root"></param>
    /// <param name="subKey"></param>
    /// <exception cref="Exception"></exception>
    public void CreateKey(RegistryRoot root, string subKey)
    {
        IntPtr hKey = GetRegistryRootKey(root);
        int result = RegCreateKeyEx(hKey, subKey, 0, null, REG_OPTION_NON_VOLATILE, KEY_WRITE, IntPtr.Zero, out IntPtr phkResult, out _);

        if (result != ERROR_SUCCESS)
        {
            throw new Exception("创建注册表key失败。 Failed to create registry key.");
        }

        RegCloseKey(phkResult);
    }

    /// <summary>
    /// 删除注册表键
    /// Delete registry key
    /// </summary>
    /// <param name="root"></param>
    /// <param name="subKey"></param>
    /// <exception cref="Exception"></exception>
    public void DeleteKey(RegistryRoot root, string subKey)
    {
        IntPtr hKey = GetRegistryRootKey(root);
        int result = RegDeleteKey(hKey, subKey);

        if (result != ERROR_SUCCESS)
        {
            throw new Exception("删除注册表key失败。Failed to delete registry key.");
        }
    }

    /// <summary>
    /// 设置注册表值
    /// Set registry value
    /// </summary>
    /// <param name="root"></param>
    /// <param name="subKey"></param>
    /// <param name="valueName"></param>
    /// <param name="value"></param>
    /// <exception cref="Exception"></exception>
    public void SetValue(RegistryRoot root, string subKey, string valueName, string value)
    {
        IntPtr hKey = GetRegistryRootKey(root);

        int result = RegOpenKeyEx(hKey, subKey, 0, KEY_WRITE, out IntPtr phkResult);
        if (result != ERROR_SUCCESS)
        {
            throw new Exception("打开注册表key失败。Failed to open registry key.");
        }

        byte[] data = Encoding.Unicode.GetBytes(value);
        result = RegSetValueEx(phkResult, valueName, 0, REG_SZ, data, data.Length);

        if (result != ERROR_SUCCESS)
        {
            throw new Exception("设置注册表值失败。Failed to set registry value.");
        }

        RegCloseKey(phkResult);
    }

    /// <summary>
    /// 获取注册表值
    /// Get registry value
    /// </summary>
    /// <param name="root"></param>
    /// <param name="subKey"></param>
    /// <param name="valueName"></param>
    /// <returns></returns>
    /// <exception cref="Exception"></exception>
    public string GetValue(RegistryRoot root, string subKey, string valueName)
    {
        IntPtr hKey = GetRegistryRootKey(root);

        int result = RegOpenKeyEx(hKey, subKey, 0, KEY_READ, out IntPtr phkResult);
        if (result != ERROR_SUCCESS)
        {
            throw new Exception("打开注册表key失败。Failed to open registry key.");
        }

        int type = 0;
        int size = 1024;
        StringBuilder data = new StringBuilder(size);

        result = RegGetValue(phkResult, null, valueName, RRF_RT_REG_SZ, out type, data, ref size);

        if (result != ERROR_SUCCESS)
        {
            throw new Exception("获取注册表的值失败。Failed to get registry value.");
        }

        RegCloseKey(phkResult);

        return data.ToString();
    }

    /// <summary>
    /// 删除注册表值
    /// Delete registry value
    /// </summary>
    /// <param name="root"></param>
    /// <param name="subKey"></param>
    /// <param name="valueName"></param>
    /// <exception cref="Exception"></exception>
    public void DeleteValue(RegistryRoot root, string subKey, string valueName)
    {
        IntPtr hKey = GetRegistryRootKey(root);

        int result = RegOpenKeyEx(hKey, subKey, 0, KEY_WRITE, out IntPtr phkResult);
        if (result != ERROR_SUCCESS)
        {
            throw new Exception("打开注册表key失败。Failed to open registry key.");
        }

        result = RegDeleteValue(phkResult, valueName);

        if (result != ERROR_SUCCESS)
        {
            throw new Exception("删除注册表的值失败。Failed to delete registry value.");
        }

        RegCloseKey(phkResult);
    }

 

 

 

标签:IntPtr,string,Invoke,int,hKey,RegistryRoot,注册表,NET
From: https://www.cnblogs.com/weskynet/p/18191869

相关文章

  • Netgear无线路由器漏洞复现(CVE-2019-20760)
    漏洞概述漏洞服务: uhttpd漏洞类型: 远程命令执行影响范围: 1.0.4.26之前的NETGEARR9000设备会受到身份验证绕过的影响解决建议: 更新版本漏洞复现操作环境: ubuntu:22.04qemu-version: 8.1.1仿真环境wgethttps://www.downloads.netgear.com/files/GDC/R9000/R9000-V1.......
  • 使用ZXing.Net生成二维码
    所需依赖组件从工程安装的ZXing.NetNuget包查看,ZXing.Net不依赖其他组件。查看package包内容,发现内部就zxing.dll和zxing.presentation.dll两个动态库文件。ZXing.Net生成的二维码形式生成的二维码形式为内存Bitmap图像对象,如果需保存为文件或Base64字符串需另外书写代码实......
  • 探究——C# .net 代码混淆/加壳
    背景:保密。过程:先查询一下常见的加壳工具:DotFuscator,官方自带,据说免费版混淆程度不高ConfuserEx,只支持.NETFramework2.0/3.0/3.5/4.0/4.5/4.6/4.7/4.8,不支持.NETCoreVirboxProtector,很好很优秀,但是收费NETReactor,最新6.9版收费,PJ版到4.9不支持.NETCoreObfu......
  • java.net.SocketException: Connection reset
    今天在学习socket编程的时候遇到了一个bug:java.net.SocketException:Connectionreset先来看一下自己的代码:服务端:publicclassServerSocketDemo{publicstaticvoidmain(String[]args){try{//建立一个ServerSocketServerS......
  • 数据库升级PostgreSql+Garnet
    目录前言PostgreSql安装测试额外Nuget安装Person.cs模拟运行Navicate连postgresql解决方案Garnet为什么要选择Garnet而不是RedisRedis不再开源Windows版的Redis是由微软维护的WindowsRedis版本老旧,后续可能不再更新Garnet性能强于Redis安装测试安装可视化工具C#代码连接测试总结......
  • Wireless Network
    描述AnearthquaketakesplaceinSoutheastAsia.TheACM(AsiaCooperatedMedicalteam)havesetupawirelessnetworkwiththelapcomputers,butanunexpectedaftershock(预余震)attacked,allcomputersinthenetworkwereallbroken.Thecomputersarerepai......
  • Advanced .Net Debugging 8:线程同步
    一、介绍这是我的《Advanced.NetDebugging》这个系列的第八篇文章。这篇文章的内容是原书的第二部分的【调试实战】的第六章【同步】。我们经常写一些多线程的应用程序,写的多了,有关多线程的问题出现的也就多了,因此,最迫切的任务就是提高解决多线程同步问题的能力。这一节......
  • Kubernetes
    Kubernetes是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,方便进行声明式配置和自动化。Kubernetes拥有一个庞大且快速增长的生态系统,其服务、支持和工具的使用范围广泛。小提示:系统配置文件Linux系统启动后,默认从以下系统配置文件加载内核参数:/run/sy......
  • .NET周刊【5月第1期 2024-05-05】
    国内文章一个开源轻量级的C#代码格式化工具(支持VS和VSCode)https://www.cnblogs.com/Can-daydayup/p/18164905CSharpier是一个开源、免费的C#代码格式化工具,特点是轻量级且依赖Roslyn引擎重构代码格式。支持的IDE包括VisualStudio(2019与2022)和VisualStudioCode等。该项......
  • skynet框架:并发热点处理方案
    对于关键流程,所有请求都要求返回有效结果,如创建socket连接:functionluasocket:connect() returnsocketcore.open(self.__host,self.__port)end显然外部调用需要获取到正确的socket句柄用于数据交互,当并发调用此接口时,所有调用都需要获取到有效的句柄以保证业务正常;方案......