当前位置:C++技术网 > 资讯 > 你真明白了注册表修改吗?正确修改注册表的键值详细介绍

你真明白了注册表修改吗?正确修改注册表的键值详细介绍

更新时间:2015-06-27 00:37:19浏览次数:1+次

    注册表对于Windows来说,就是心脏。各种功能经常需要修改注册表,但是修改注册表,不仅仅是使用几个函数那么简单。正是因为之前的浮躁,我自以为会了,结果就一个修改注册表键值,花费了一个下午。实际上,我因为之前的浮躁没有踏实学。当问题出现时会出现各种连带的问题,这时才会发现自己之前学的是多么渣。然而解决了问题之后,又发现其实就那么点小问题没有注意。不过我可以说,这不仅仅是一个小小的忽略,而是根本就没有真正明白。还是那句话,浮躁的心学不好任何东西。
    对于注册表的修改,以前用过,但是很久没用了,不会用了。或许以前根本就没有非常明白吧,所以现在一说修改注册表,感觉很激动,似乎很轻而易举的事情一样。然而真正要做的时候,却发现有太多的问题,导致一个小小的修改,浪费了不少时间。而网上没有查到资料,这么简单但是容易出错的问题,竟然没有人说明,也让大家学习带来了极大的困扰。在此总结一下,出现的各种问题,希望大家可以有个清晰的参考。在此过程中,因为修改注册表值不对导致VS偶然出现了一个Bug,导致程序无法退出。在任务管理器关闭时360竟然提示不能退出360进程。这也太奇葩了。如果不折腾,按部就班的写代码,或许永远都遇不到这些问题,不过那样学的不会很深刻。下面爆图:

    1.强制关闭进程
 
    2.360阻止关闭进程
 
    3.系统自己阻止关闭进程,因为程序内部修改注册表错误。
 
    4.无法关闭进程导致VS无法再调试,因此修改VS生成的EXE文件名。
 
    5.下面是修改注册表错误的提示
 
    以上就是错误的修改注册表,导致VS出现问题,结果造成的问题。此问题出现后,即使修改了生成的EXE,也能正确的生成新的EXE,然而却不能调试了。这里也就断定这个是VS2008的一个Bug.这也是没有真正弄明白正确修改注册表的一个意外的收获吧。看来是需要好好了解一下如何修改注册表。
    下面介绍如何正确修改注册表键值。这里不是全面介绍注册表编程,所以,只对关键位置做解释。

    先做个基本的介绍:
    1.注册表是多级的结构,树状表示。每一级类似于目录,在注册表中叫做项,即注册表项。而在最根部有几个熟知的注册表项,如HKEY_CURRENT_USER。它的子级都是它的子项。一个注册表项有一个或者多一个键,叫做注册表键。我们一般要修改一个已经存在的注册表键,从能可以修改系统或者浏览器的设置等。
    2.如果我们要修改这些键值,我需要先打开这个注册表键所在的注册表项,使用API函数RegOpenKey或者RegOpenKeyEx,函数的具体使用就不细讲,参考MSDN的说明即可。然而使用过程中出现的一个问题就是,给定的注册表项写法不对,导致找不到注册表项。我们可以直接打开多级注册表项,而不需要一级一级的打开,就像打开目录一样。代码如下: 

HKEY hKey;
RegOpenKey(HKEY_CURRENT_USER,_T("Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\"), &hKey);

     在第一个参数,传递注册表根项,就是最开始的项。然后第二个参数传递一个注册表项的路径,这里就是打开这个Windows项,你还可以直接打开Windows项下的项。此时,开始我是看的网上的一篇文章,第二个参数是Software//Microsoft//Windows// 这种写法,结果提示找不到这个项,这么坑。后来我估计是这个斜杠出的问题,就使用\\来测试结果成功了。这里不能乱用。第三个参数就是打开注册表项得到的项的句柄,用于操作此项的键的。
    3.注册表项的键有几种类型,一个是REG_SZ字符串类型,一个是REG_DWORD类型,一个是REG_BINARY二进制值类型。不同的类型,修改值的写法都不一样,就是在此处,让我花费了很多时间,后来测试成功了。网上没有文章说这个问题,估计没有几个人仔细研究吧,或者是不屑研究,都是按部就班的用的吧。下面给出实现修改注册表键的代码: 

TCHAR tcPath[100]=_T("C:\\1.theme");// - 当前主题文件路径
DWORD dwVal = 0;
RegSetKeyValue(hKey,_T(""),_T("CurrentTheme"),REG_SZ, strPath,100*sizeof(TCHAR));
RegSetKeyValue(hKey,_T(""),_T("ThemeChangesDesktopIcons"),REG_DWORD, &dwVal,sizeof(DWORD));
RegSetKeyValue(hKey,_T(""),_T("二进制的一个键名称"),REG_BINARY, &dwVal,sizeof(DWORD));

     注:第一个参数是由RegOpenKey打开得到的注册表项句柄,也可以通过创建得到,此处不讨论。第二个参数是打开的注册表项的子项,如果只是修改打开的注册表项,那就传入空字符即可。第三个参数为注册表项的键,如果填入空字符,则是默认的键,如图:

    第四个参数就是设置要修改的键的类型,不同的类型,后面的值的写法不一样。如上代码所示,REG_SZ类型的赋值,直接传入一个字符串的地址即可。然后指定字符串的字节大小。REG_DWORD为DWORD类型,所以第五个参数要接受值的地址。当然就不能直接传入常量数字,所以要定义一个变量,然后给变量赋值,将变量的地址传入第五个参数。最后一个参数就是变量的字节大小。几个类型都是一样的。REG_BINARY类型传值和REG_DWORD一样。
    在此处,我在传值给REG_DWORD时开始是用常量数字,但是总是不成功,后来感觉是不能接受常量,所以就用变量地址传入,结果就正确了。有的时候不能想当然,因为函数内部会对传入的变量进行修改,如果是常量数字,则没法修改,就导致失败。这是API函数经常用到的特点,特别需要注意。二进制的值类型REG_BINARY就按照DWORD来传值就可以了。只是它在注册表内部会以二进制表示值而已,我们在设置值用正常的值就可以正确设置。
    到此,修改就结束了,最后要将打开的注册表项关闭掉,释放资源。调用函数RegCloseKey(hKey);即可。
    而开始我以为使用RegSetValue就可以修改注册表键,然而大量的尝试结果发现,每次都是创建了一个项,然后给这个项设置了一个默认值。网上一些文章都这么说的,太坑了。问题出在没有对注册表项和注册表键概念很清楚,也对API函数不熟,也被网上的文章误导,都说的不细致,不清不楚,害死人。RegSetValue是用来创建和设置一个注册表项的默认值的。具体的参看MSDN的详细解释。