利用VC访问INI文件和系统注册表

.INI文件
    INI文件(Initialization file
  ,又称为初始化文件)是用来保存应用程序设置和选项的一种特殊的ASCII文件,以“.ini”作为文件扩展名,也被称做配置文件或概要文件(Profile)。除了各个应用程序可以拥有自己私有的初始化文件外,Windows系统还提供有一个系统的初始化文件Win.ini,并由此对当前的Windows系统进行配置,同时也可以在其内记录系统内其他应用程序在运行时的选项。
    通常为应用程序所私有的初始化文件比较小,这样可以减少程序在初始化时所读取的信息量,从而提高程序的启动速度。而系统初始化文件Win.ini由于除了记录有关系统的大量信息外,还存储着许多其他应用软件的初始化数据,因此其通常比较庞大,访问的数据量要远比私有的配置文件大得多。如没有必要,一般不建议对Win.ini文件进行操作,但如果待存取的信息涉及到Windows系统环境或是其他应用程序时,
  就必须对Win.ini进行读写访问,并在访问的同时发送WM_WININICHANGE消息给所有的顶层窗口,通知其他进程系统初始化文件已被更改。
    配置文件里的信息之所以能为系统和众多不同类型的应用程序读取并识别,是由于其内部对数据的存取采用了预先约定的“项-值对(Entry-value
  pairs)”存储结构, 并对待存取的数据分门别类地进行存储。下面是系统目录下Win.ini文件的部分内容:
        [windows]
        load=
        run=
        NullPort=None
        [Desktop]
        WallpaperStyle=2
        Pattern=(无)
    在此,配置文件将信息分为若干“节”,节标题放在方括号中,如“[Desktop]”就是Desktop节,在每一个节中包含了一些与之相关的“项”,并通过等号对其进行赋值。一般形式如下:
        [SECTION]
        ENTRY=VALUE
    在初始化文件中,VALUE值只能有两种数据类型:数值和字符串。Windows分别为这两种数据类型提供了两套API函数对初始化文件进行数据读取,在写入初始化文件时则只支持对字符串的写入,数值等类型必须先进行数据类型的转换,然后才能写入到初始化文件。
私有初始化文件的访问
  对私有初始化文件的数据存取是由GetPrivateProfileInt()、GetPrivateProfileString()和WritePrivateProfileString()等三个API函数来完成的。其函数说明如下:
UINT GetPrivateProfileInt(LPCTSTR lpAppName, // 节名地址
 LPCTSTR lpKeyName, // 项名地址
 INT nDefault, // 在项名没有找到时返回的缺省值
 LPCTSTR lpFileName // 初始化文件名地址
);
DWORD GetPrivateProfileString(LPCTSTR lpAppName, // 节名地址
 LPCTSTR lpKeyName, // 项名地址
 LPCTSTR lpDefault, // 缺省字符串
 LPTSTR lpReturnedString, // 存放字符串的缓冲区地址
 DWORD nSize, // 缓冲区大小
 LPCTSTR lpFileName // 初始化文件名地址
);
BOOL WritePrivateProfileString(LPCTSTR lpAppName, // 节名地址
 LPCTSTR lpKeyName, // 项名地址
 LPCTSTR lpString, // 要写入的字符串地址
 LPCTSTR lpFileName // 初始化文件名地址
);
  其中,GetPrivateProfileInt()返回的是初始化文件lpFileName中lpAppName节内lpKeyName项的整数值,如果没有找到该项则返回缺省值nDefault。如果此项目存在,但值不为整数,则返回0。如果某项目的值中含有非数字字符则只返回第一个非数字前的字符,例如对于“Value = 21century”则只返回数值21。初始化文件名lpFileName可以是全路径也可以只是文件名,如果不指定具体路径,Windows系统将在系统目录对文件进行寻找。GetPrivateProfileString()和WritePrivateProfileString()的用法基本与之类似,只是处理对象的数据类型不同。
  私有初始化文件主要用来保存同应用程序当前状态相关的一些信息,当程序退出后,这些信息由于已写入到初始化文件而得以保留,当程序再次运行时,可以通过对此初始化文件各项数据的读取而得知此应用程序在上次运行期间的相关信息。下面这段代码即通过对私有初始化文件的访问而对程序的运行次数和上一次的运行日期进行记录:
// 获取当前应用程序全路径
GetModuleFileName(NULL, buffer, MAX_PATH);
sPath = CString(buffer);
sPath = sPath.Left(sPath.ReverseFind('//'));
// 得到初始化文件的全路径
sPath += " //Sample04.ini";
// 得到程序累计运行次数
UINT Time = GetPrivateProfileInt("PROGRAM", "RUNTIME", 0, sPath);
// 得到上次运行日期
GetPrivateProfileString("DATE", "LAST", "2002-11-1", buffer, 1000, sPath);
// 显示从初始化文件获取到的文件信息
sMsg.Format("本软件共运行过%d次,上次运行日期为%s", Time, CString(buffer));
AfxMessageBox(sMsg);
// 累加运行次数,并保存到初始化文件
Time++;
sTime.Format("%d", Time);
WritePrivateProfileString("PROGRAM", "RUNTIME", sTime, sPath);
// 获取当前日期,并保存到初始化文件
CTime tm = CTime::GetCurrentTime();
sDate.Format("%d-%d-%d", tm.GetYear(), tm.GetMonth(), tm.GetDay());
WritePrivateProfileString("DATE", "LAST", sDate, sPath);
  在程序执行后,初始化文件Sample04.ini的内容为:
[DATE]
LAST =2002-11-12
[PROGRAM]
RUNTIME =1
 对Win.ini的访问
    系统目录下的Win.ini是一种特殊的初始化文件,主要为系统提供初始化服务,在系统启动时将被系统所访问,并根据其所保存的参数值对系统进行配置。Windows专门提供了三个API函数GetProfileInt()、GetProfileString()和WriteProfileString()对Win.ini进行读写访问,其函数用法同访问私有初始化文件的那几个函数非常类似,只是不必再去指定初始化文件名。下面是这三个函数的原型声明:
        UINT GetProfileInt(LPCTSTR lpAppName, // 节名地址
         LPCTSTR lpKeyName, // 项名地址
         INT nDefault // 在项名没有找到时返回的缺省值
        );
        DWORD GetProfileString(LPCTSTR lpAppName, // 节名地址
         LPCTSTR lpKeyName, // 项名地址
         LPCTSTR lpDefault, // 缺省字符串地址
         LPTSTR lpReturnedString, // 存放字符串的缓存的地址
         DWORD nSize // 缓存的大小
        );
        BOOL WriteProfileString(LPCTSTR lpAppName, // 节名地址
         LPCTSTR lpKeyName, // 项名地址
         LPCTSTR lpString // 要写入字符串的地址
        );
    只要对前面对私有初始化文件进行访问的代码稍加改动即可将程序的配置信息添加到Win.ini中,改动后的代码如下:
        // 得到程序累计运行次数
        UINT Time = GetProfileInt("PROGRAM", "RUNTIME", 0);
        // 得到上次运行日期
        GetProfileString("DATE", "LAST", "2002-11-1", buffer, 1000);
        // 显示从初始化文件获取到的文件信息
        sMsg.Format("本软件共运行过%d次,上次运行日期为%s", Time, CString(buffer));
        AfxMessageBox(sMsg);
        // 累加运行次数,并保存到初始化文件
        Time++;
        sTime.Format("%d", Time);
        WriteProfileString("PROGRAM", "RUNTIME", sTime);
        // 获取当前日期,并保存到初始化文件
        CTime tm = CTime::GetCurrentTime();
        sDate.Format("%d-%d-%d", tm.GetYear(), tm.GetMonth(), tm.GetDay());
        WriteProfileString("DATE", "LAST", sDate);
    由于Win.ini文件是系统初始化文件,在程序没有运行前文件内不含“DATE”和“PROGRAM”等自定义的节以及其下各项,因此在程序第一次执行后,将由WriteProfileString()函数向Win.ini文件末尾创建相关节、项,并完成数据的写入。
对系统注册表的访问
    初始化文件在早期Windows编程中使用非常普遍,各种系统初始化文件如Win.ini、System.ini等甚至还担负了对系统软、硬件配置以及用户环境等进行控制的重任。
  在目前的Windows编程中,虽然初始化文件还以其方便简洁的编程方法而继续使用,但其使用范围已大不如前,尤其是在为系统提供配置信息等方面的功能被大大削弱,几乎不起什么重要作用。取而代之的是一种被称为“系统注册表”的二进制数据文件,为应用程序和系统的组成部分提供存储和检索相关的配置信息。该文件只能通过系统提供的注册表编辑器(Registry
  Editor)进行编辑,或是在程序中通过专门用于注册表访问的API函数对其进行编辑。
    系统注册表是一个多层次的结构树,在树的根部共有六个预定义键:HKEY_CLASSES_ROOT、HKEY_CURRENT_USER、HKEY_LOCAL_MACHINE、KEYI_USERS、HKEY_CURRENT_CONFIG和HKEY_DYN_DATA(HKEY_DYN_DATA键只对于Windows
  9x而言)。在每一个预定义键下面还包含有众多的树节点,每一个节点都是注册表的关键字,均代表了一个特定的配置项目。在节点展开后又包含有子关键字,直至最后的节点。其中HKEY_CLASSES_ROOT键主要保存了文档类型和属性等信息以及同应用程序相关的分类信息等。HKEY_CURRENT_USER键主要对用户的当前系统配置进行记录。HKEY_LOCAL_MACHINE键对计算机的状态信息进行记录。KEYI_USERS键对当前系统的所有用户信息进行组织。HKEY_CURRENT_CONFIG和HKEY_DYN_DATA键则分别对硬件配置信息和同动态注册相关的数据信息进行记录。
    Windows提供了近30个API函数用于访问系统注册表,这些API函数提供了对注册表进行键的创建、打开、关闭、删除和对键值的设置、删除等功能。通常对注册表比较常用的操作不外乎对键或键值的添加、删除与修改等,而注册表中的各个键均有其特定的作用,通过对这些键的访问和对键值的适当修改可以获取到几乎所有的同系统有关的软、硬件信息并可对系统性能进行优化。例如,有关用户的信息位于系统注册表的HKEY_LOCAL_MACHINE/Software/Microsoft/Windows
  NT/CurrentVersion/下(对于Windows 2000
  Professional而言),键值名RegisteredOwner和RegisteredOrganization分别表示用户的姓名和公司名称。如需要在程序中获取该信息,只要访问此键值的内容即可。
    读取注册表中某个键值的内容首先要通过RegOpenKey()或RegOpenKeyEx()函数打开相应的键,然后再调用RegQueryValue()或RegQueryValueEx()检索指定键值的内容,操作完成后调用RegClosefKey()将打开的键关闭,结束对注册表的访问。其中RegOpenKeyEx()和RegQueryValueEx()的功能比较强大,分别是对RegOpenKey()和RegQueryValue()在功能上的扩展,其函数原型为:
        LONG RegOpenKeyEx(HKEY hKey, // 待打开的预定义键
         LPCTSTR lpSubKey, // 待打开的子键的地址
         DWORD ulOptions, // 保留
         REGSAM samDesired, // 安全访问掩码
         PHKEY phkResult // 打开的键的地址
        );
        LONG RegQueryValueEx(HKEY hKey, // 待检索的键
         LPTSTR lpValueName, // 要检索的键值名称的地址
         LPDWORD lpReserved, // 保留
         LPDWORD lpType, // 键值类型的地址
         LPBYTE lpData, // 存放检索结果的缓存的地址
         LPDWORD lpcbData // 缓存长度的地址
        );
    最后,给出了通过访问注册表键值而得到用户注册信息的简单程序示例,该示例片段展示了对系统注册表指定键的打开、检索以及关闭等基本处理过程:
        // 打开键
        HKEY hKEY;
        LPCTSTR Rgspath = "Software//Microsoft//Windows NT//CurrentVersion";
        LONG ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, Rgspath, 0, KEY_READ,
&hKEY);
        if(ret != ERROR_SUCCESS)
        {
         RegCloseKey(hKEY);
         return;
        }
        // 读取键值内容
        DWORD dwInfoSize;
        DWORD type = REG_SZ;
        BYTE UserInfo[255];
        ret = RegQueryValueEx(hKEY, "RegisteredOwner", NULL, &type, UserInfo,
        &dwInfoSize);
        if(ret!=ERROR_SUCCESS)
        {
         RegCloseKey(hKEY);
         return;
        }
        ……
        // 关闭键
        RegCloseKey(hKEY);
注册表键的访问权限
    基于注册表在Windows操作系统中的重要地位和所起的特殊作用,非常有必要对其进行一些安全性方面的设置。虽然可以通过设置用户权限来限制对注册表中敏感数据的访问,但该由该用户所使用的应用程序却很有可能必须访问此数据。这就需要能在程序中对注册表键的安全性级别进行修改。如在使用RegOpenKeyEx()打开某个键时,可用WRITE_OWNER访问权限打开,并将返回的指向注册表的句柄传递给对RegSetKeySecurity()的调用,以此取得对键的所有权:
        RegOpenKeyEx(HKEY_CLASSES_ROOT, “TestValue”, 0, WRITE_OWNER, &hKey);
        RegSetKeySecurity(hKey, OWNER_SECURITY_INFORMATION, &Security);
    其中,Security是SECURITY_DESCRIPTOR结构的一个对象。除上面使用的WRITE_OWNER之外,对注册表键的访问权限还有DELETE、READ_CONTROL、WRITE_DAC等标准访问权限以及注册表所专有的访问权限KEY_CREATE_LINK、KEY_CREATE_SUB_KEY、KEY_EXECUTE、KEY_ENUMERATE_SUB_KEYS、KEY_NOTIFY、KEY_QUERY_VALUE、KEY_SETVALUE、KEY_ALL_ACCESS、KEY_READ和KEY_WRITE等。
    小结
    在应用程序中使用初始化文件和注册表将可以完成许多特殊的功能,通常应用较多的是用来记录和获取程序在上一次运行的状态配置,使程序具有“记忆”功能。而有些黑客软件也同样是通过向初始化文件和注册表写入某些特定信息而使其具有开机运行的功能。
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
信息开发系统是一种用于收集、整理和处理信息的工具,它能够帮助人们高效地管理和利用大量的信息资源。利用VC(Visual C++)开发一个信息开发系统可以是一个很好的选择。 首先,VC是一种强大的集成开发环境,它提供了一套丰富的开发工具和库,使开发者能够更快速、更灵活地开发应用程序。通过使用VC,我们可以方便地创建用户界面、处理数据、连接数据库等,从而实现一个功能完善的信息开发系统。 其次,信息开发系统通常需要处理大量的数据,并进行复杂的数据操作和分析。VC提供了高效的数据处理工具和算法库,可以帮助我们实现数据的快速读取、存储和分析。此外,VC还提供了丰富的图形化界面设计工具,可以帮助我们设计出直观、易用的界面,方便用户进行操作和管理数据。 最后,VC开发的应用程序具有良好的可移植性和跨平台性。利用VC开发的信息开发系统可以在Windows操作系统上运行,并且可以方便地进行移植到其他平台,如Linux或MacOS等。这样,我们可以更好地满足不同用户的需求,并使系统更具灵活性和可扩展性。 综上所述,利用VC开发一个信息开发系统可以帮助我们实现高效、灵活、可移植的信息管理和利用。无论是对于个人用户还是企业组织,这样的系统都可以提高工作效率和信息利用率,是一种有着广泛应用前景的开发方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值