[C#]注册表操作

简介: 原文:[C#]注册表操作概念在介绍注册表操作前,有必要了解注册表的一些基本常识。在此简要介绍一下。  注册表注册表(Registry,繁体中文版Windows称之为登录档)是Microsoft Windows中的一个重要的数据库,用于存储系统和应用程序的设置信息。
原文: [C#]注册表操作

概念

在介绍注册表操作前,有必要了解注册表的一些基本常识。

在此简要介绍一下。 

注册表

注册表(Registry,繁体中文版Windows称之为登录档)是Microsoft Windows中的一个重要的数据库,用于存储系统和应用程序的设置信息。注册表组织层次结构的格式,基于存储在它的元素的逻辑顺序。 当将信息存储在注册表中,选择要存储的信息类型所基于的适当位置。

在Windows 3.x操作系统中,注册表是一个极小文件,其文件名为Reg.dat,里面只存放了某些文件类型的应用程序关联,大部分的设置放在Win.ini、System.ini等多个初始化INI文件中。由于这些初始化文件不便于管理和维护,时常出现一些因INI文件遭到破坏而导致系统无法启动的问题。为了使系统运行得更为稳定、健壮,Windows 95/98设计师们借用了Windows NT中的注册表的思想,将注册表引入到Windows 95/98操作系统中,而且将INI文件中的大部分设置也移植到注册表中,因此,注册表在Windows 95/98操作系统的启动、运行过程中起着重要的作用。


HKEY(主键)

HEKY:“根键”或“主键”。

windows7中有5个主键:

HKEY_CLASSES_ROOT:保存了所有应用程序运行时必需的信息。

HKEY_CURRENT_USER:保存统当前的用户信息。

HKEY_LOCAL_MACHINE:保存了注册表里的所有与这台计算机有关的配置信息。

HKEY_USERS:保存了缺省用户设置和登录用户的信息。虽然它包含了所有独立用户的设置,但在用户未登录时用户的设置是不可用的。

HKEY_CURRENT_CONFIG :保存了系统中现有的所有配置文件的细节。


key(键)

它包含了附加的文件夹和一个或多个值。


subkey(子键)

在某一个键(父键)下面出现的键(子键)。

 

打开注册表的方法

点击 开始 -> 运行 -> regedit

 

注册表操作

RegistryKey

表示 Windows 注册表中的项级节点。 此类是注册表封装。

所属命名空间为Microsoft.Win32

常用方法

CreateSubKey:创建或打开一个子表项

OpenSubKey:打开一个子表项

SetValue:设置一个变量的值

GetValue:获取一个变量的值

DeleteValue:删除一个变量

MSDN官方例子

using System;
using System.Security.Permissions;
using Microsoft.Win32;
 
class RegKey
{
     static  void Main()
    {
         //  Create a subkey named Test9999 under HKEY_CURRENT_USER.
        RegistryKey test9999 =
            Registry.CurrentUser.CreateSubKey( " Test9999 ");
         //  Create two subkeys under HKEY_CURRENT_USER\Test9999. The
        
//  keys are disposed when execution exits the using statement.
         using(RegistryKey
            testName = test9999.CreateSubKey( " TestName "),
            testSettings = test9999.CreateSubKey( " TestSettings "))
        {
             //  Create data for the TestSettings subkey.
            testSettings.SetValue( " Language "" French ");
            testSettings.SetValue( " Level "" Intermediate ");
            testSettings.SetValue( " ID "123);
        }
 
         //  Print the information from the Test9999 subkey.
        Console.WriteLine( " There are {0} subkeys under {1}. ",
            test9999.SubKeyCount.ToString(), test9999.Name);
         foreach( string subKeyName  in test9999.GetSubKeyNames())
        {
             using(RegistryKey
                tempKey = test9999.OpenSubKey(subKeyName))
            {
                Console.WriteLine( " \nThere are {0} values for {1}. ",
                    tempKey.ValueCount.ToString(), tempKey.Name);
                 foreach( string valueName  in tempKey.GetValueNames())
                {
                    Console.WriteLine( " {0,-8}: {1} ", valueName,
                        tempKey.GetValue(valueName).ToString());
                }
            }
        }
 
         using(RegistryKey
            testSettings = test9999.OpenSubKey( " TestSettings "true))
        {
             //  Delete the ID value.
            testSettings.DeleteValue( " id ");
 
             //  Verify the deletion.
            Console.WriteLine(( string)testSettings.GetValue(
                 " id "" ID not found. "));
        }
 
         //  Delete or close the new subkey.
        Console.Write( " \nDelete newly created registry key? (Y/N)  ");
         if(Char.ToUpper(Convert.ToChar(Console.Read())) ==  ' Y ')
        {
            Registry.CurrentUser.DeleteSubKeyTree( " Test9999 ");
            Console.WriteLine( " \nRegistry key {0} deleted. ",
                test9999.Name);
        }
         else
        {
            Console.WriteLine( " \nRegistry key {0} closed. ",
                test9999.ToString());
            test9999.Close();
        }
    }
}

 

应用案例

获取程序的版本号和安装路径

代码:获取OFFICE的版本号和安装路径

using System;
using System.Windows.Forms;
using Microsoft.Win32;
 
namespace RegistryUtil {
        static  class Program {
               ///   <summary>
              
///  应用程序的主入口点。
              
///   </summary>
              [STAThread]
               static  void Main() {
                     Application.EnableVisualStyles();
                     Application.SetCompatibleTextRenderingDefault( false);
 
                      string version =  null;
                      string path =  null;
                     GetOfficeInfo( out version,  out path);
                     Console.WriteLine( string.Format( " OFFICE 版本号:{0}, 安装路径:{1} ", version, path));
              }
 
               ///   <summary>
              
///  获取注册表中的OFFICE版本和安装路径信息
              
///   </summary>
              
///   <param name="version"> 出参,版本号 </param>
              
///   <param name="path"> 出参,安装路径 </param>
              
///   <returns> int错误码 </returns>
               public  static  int GetOfficeInfo( out  string version,  out  string path) {
                     path =  string.Empty;  //  OFFICE安装路径
                     version =  string.Empty;  //  OFFICE版本
 
                      int result =  0;
                     RegistryKey regKey =  null;
 
                      try {
                            regKey = Registry.LocalMachine.OpenSubKey( @" SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\Excel.exe ");  //  Excel程序的注册表路径
                             string regValue = regKey.GetValue( " Path ").ToString();
                             string temp = regValue.Substring( 0, regValue.Length -  1);
                             string versionName = temp.Substring(temp.LastIndexOf( " \\ ") +  1);
 
                             switch (versionName) {
                                    case  " Office11 ":   // 检查本机是否安装Office2003
                                          version =  " Office2003 ";
                                           break;
                                    case  " Office12 ":   // 检查本机是否安装Office2007
                                          version =  " Office2007 ";
                                           break;
                                    case  " Office14 ":   // 检查本机是否安装Office2010
                                          version =  " Office2010 ";
                                           break;
                                    case  " Office15 ":   // 检查本机是否安装Office2013
                                          version =  " Office2013 ";
                                           break;
                                    default:
                                          version =  " 未知版本! ";
                                           break;
                            }
                            path = regValue;
 
                     }  catch (Exception ex) {
                            result = - 1;
                            Console.WriteLine(ex.Message);
                     }  finally {
                             if ( null != regKey) {
                                   regKey.Close();
                                   regKey =  null;
                            }
                     }
 
                      return result;
              }
       }
}

 

如何设置程序开机自启动

如果想要将一个exe程序设置为开机自启动,其实就是在HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run注册表项中添加一个注册表变量,这个变量的值是程序的所在路径。

具体操作步骤是:

1、使用RegistryKey类的CreateSubKey方法打开HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run变量,如果不存在,这个方法会直接创建。

2、如果是添加一个变量的键值可以使用RegistryKey类的SetValue方法;

如果是删除一个变量的键值可以使用RegistryKey类的DeleteValue方法。

代码: 设置程序开机自启动状态

using System;
using System.Windows.Forms;
using Microsoft.Win32;
 
namespace RegistryUtil {
        static  class Program {
               ///   <summary>
              
///  应用程序的主入口点。
              
///   </summary>
              [STAThread]
               static  void Main() {
                     Application.EnableVisualStyles();
                     Application.SetCompatibleTextRenderingDefault( false);
                     SetAutoBootStatu( true);
              }
 
               ///   <summary>
              
///  在注册表中添加、删除开机自启动键值
              
///   </summary>
               public  static  int SetAutoBootStatu( bool isAutoBoot) {
                      try {
                             string execPath = Application.ExecutablePath;
                            RegistryKey rk = Registry.LocalMachine;
                            RegistryKey rk2 = rk.CreateSubKey( " Software\\Microsoft\\Windows\\CurrentVersion\\Run ");
                             if (isAutoBoot) {
                                   rk2.SetValue( " MyExec ", execPath);
                                   Console.WriteLine( string.Format( " [注册表操作]添加注册表键值:path = {0}, key = {1}, value = {2} 成功 ", rk2.Name,  " TuniuAutoboot ", execPath));
                            }  else {
                                   rk2.DeleteValue( " MyExec "false);
                                   Console.WriteLine( string.Format( " [注册表操作]删除注册表键值:path = {0}, key = {1} 成功 ", rk2.Name,  " TuniuAutoboot "));
                            }
                            rk2.Close();
                            rk.Close();
                             return  0;
                     }  catch (Exception ex) {
                            Console.WriteLine( string.Format( " [注册表操作]向注册表写开机启动信息失败, Exception: {0} ", ex.Message));
                             return - 1;
                     }
              }
 
       }
}

需要注意的是

Windows中微软的注册表信息是分32位和64位的

32位:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft

64位:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft

以下代码

RegistryKey rk = Registry.LocalMachine;
RegistryKey rk2 = rk.CreateSubKey( " Software\\Microsoft\\Windows\\CurrentVersion\\Run ");
rk2.SetValue( " MyExec ", execPath);

在32位机器上执行,那么没有问题,变量会创建在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run下。但是如果在64位机器上执行,会自动创建在

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run

 

如何添加、删除、刷新环境变量

很多时候,我们需要设置系统环境变量(比如:设置Java jdk、tomcat的环境变量),使得计算机可以识别要执行程序的路径,这样就可以直接运行它。我个人理解,环境变量就像是计算机的全局变量,只要设置了,系统就可以任何文件路径识别它。

学计算机的基本都会人工大法

点击 计算机->属性->高级系统设置->环境变量->系统环境变量

然后在Path中添加你要执行程序的所在路径。So Easy。

如果要在程序中去设置,该如何做呢。

首先,你需要了解的是:

系统环境变量列表实际上和注册表中的HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session Manager\Environment项一一对应。

你修改了这个注册表项的键值就是在修改系统环境变量。

无论是添加、删除一个执行路径都需要执行以下步骤:

1、 使用RegistryKey类的OpenSubKey方法打开HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session Manager\Environment表项。

2、 使用RegistryKey类的GetValue方法读取表项中的变量。

3、 键值就是一个字符串,修改后,使用RegistryKey类的SetValue方法写入注册表中。

4、 使用windows系统函数SendMessageTimeout刷新环境变量。

需要说明的是:如果不刷新环境变量。计算机并不一定让已修改的变量立即生效。虽然你打开注册表或环境变量时,可以看到值确实已经发生了变化。

此外,还需要注意一点,windows还有一个SendMessage函数。此函数必须得到消息回应才会继续执行,使用此函数发送刷新变量消息,可能会使程序挂住。

代码:将当前执行程序的路径写入系统环境变量Path中

using System;
using System.IO;
using System.Windows.Forms;
using Microsoft.Win32;
using System.Runtime.InteropServices;
namespace RegistryUtil {
        static  class Program {
               ///   <summary>
              
///  应用程序的主入口点。
              
///   </summary>
              [STAThread]
               static  void Main() {
                     Application.EnableVisualStyles();
                     Application.SetCompatibleTextRenderingDefault( false);
                     AddValueToSysPathEnv(Environment.CurrentDirectory);
              }
 
               ///   <summary>
              
///  为系统环境变量Path添加一个path路径
              
///   </summary>
              
///   <param name="key"></param>
              
///   <param name="value"></param>
              
///   <returns></returns>
               public  static  int AddValueToSysPathEnv( string value) {
                      int code =  0;
                     RegistryKey regEnvironment =  null;
                      try {
                            regEnvironment = Registry.LocalMachine.OpenSubKey( " SYSTEM\\ControlSet001\\Control\\Session Manager\\Environment "true);
                             if ( null == regEnvironment) {
                                    return - 1;
                            }
                             string regValue = ( string)regEnvironment.GetValue( " Path ");
 
                            regValue = value + Path.PathSeparator + regValue;
                            Console.WriteLine( " 环境变量:  " + regValue);
                            regEnvironment.SetValue( " Path ", regValue);
 
                             //  刷新环境变量,否则不一定即时生效
                            IntPtr result;
                            SendMessageTimeout( new IntPtr(HWND_BROADCAST),
                                                                WM_SETTINGCHANGE,
                                                                IntPtr.Zero,
                                                                 " Environment ",
                                                                SendMessageTimeoutFlags.SMTO_ABORTIFHUNG,
                                                                 200,
                                                                 out result);
                            Console.WriteLine( " Result:  " + result);
                            regEnvironment.Flush();
                     }  catch (Exception ex) {
                            Console.WriteLine(ex);
                            code = - 1;
                     }  finally {
                             if ( null != regEnvironment) {
                                   regEnvironment.Close();
                                   regEnvironment =  null;
                            }
                     }
 
                      return code;
              }
 
              [Flags]
               public  enum SendMessageTimeoutFlags :  uint {
                     SMTO_NORMAL =  0x0000,
                     SMTO_BLOCK =  0x0001,
                     SMTO_ABORTIFHUNG =  0x0002,
                     SMTO_NOTIMEOUTIFNOTHUNG =  0x0008
              }
               const  int WM_SETTINGCHANGE =  0x001A;
               const  int HWND_BROADCAST =  0xffff;
 
               ///   <summary>
              
///  windows发送消息函数
              
///   </summary>
              [DllImport( " user32.dll ", SetLastError =  true, CharSet = CharSet.Auto)]
               public  static  extern IntPtr SendMessageTimeout(
                       IntPtr hWnd,
                        uint Msg,
                       IntPtr wParam,
                        string lParam,
                       SendMessageTimeoutFlags fuFlags,
                        uint uTimeout,
                        out IntPtr lpdwResult);
       }
}


参考资料

RegistryKey

https://msdn.microsoft.com/zh-cn/library/microsoft.win32.registrykey.aspx

SendMessageTimeout

https://msdn.microsoft.com/en-us/library/windows/desktop/ms644952(v=vs.85).aspx

目录
相关文章
|
7月前
|
存储 安全 Windows
注册表的基础
注册表的基础
48 0
简单的注册表代码记录
简单的注册表代码记录
65 0
C#编程-143:删除注册表
C#编程-143:删除注册表
106 0
修改注册表/文件报错
一般这种报错都是提示权限有问题,我们可以手动修改注册表权限
修改注册表/文件报错
|
安全 Windows 数据库
注册表与木马(一)——注册表读写
 木马是什么?     木马(网络程序) = 客户端程序(控制端) + 服务端(被控端)     服务端程序开启远程后门     客户端使用Telnet进行远程控制     服务端程序需要在每次电脑开机时运行,这就需要在注册表中添加开机启动。
1279 0
|
安全 Shell Windows