通过注册表获取程序安装目录

简介

​ 应用程序在安装过程中会在注册表中写入相应的值,以将自己与某些文件类型或程序关联,而同时,应用程序的安装目录或包含安装目录的信息一般也会写入注册表中,所以我们可通过注册表来获取一些应用程序的安装目录。

在注册表中找到需要的值

​ 以Firefox为例,使用win+R快捷键打开运行目录,输入regedit打开注册表编辑器,在其中找到所需值的目录:

Run

InstallDirectory

​ 我们所需的值存储在计算机\\HKEY_LOCAL_MACHINE\\SOFTWARE\\Mozilla\\Mozilla Firefox\\67.0.4 (x64 zh-CN)\\Main目录下的Install Directory值下。

从注册表取值

​ 打开和读取注册表可以用RegOpenKeyEx()RegQueryValueEx()两个函数,其中RegOpenKeyEx()负责打开注册表,RegQueryValueEx()负责从中读取值。函数的用法如下:

1
2
3
4
5
RegOpenKeyEx(HKEY_LOCAL_MACHINE,
TEXT(tempPath.c_str()),
0,
KEY_QUERY_VALUE | KEY_WOW64_64KEY,
&hKey);

​ 第一个参数表示打开的注册表的最上级目录,其有几个默认可选值:HKEY_LOCAL_MACHINEHKEY_CLASSES_ROOTHKEY_CURRENT_USER等,同时也可以是由RegOpenKeyEx()等函数返回的句柄。第二个参数为第一个参数的子项,其通常为我们要打开的值的路径。第三个参数为保留值,一般置0。第四个参数限制注册表的打开方式,此处表示以只读方式打开,同时限定其以64位的形式返回注册表的值(如果不限定返回为64位,在64位的机器上必须使用64位编译环境编译才能运行)。第五个参数存储此函数返回的句柄。具体说明见MicrosoftDoc

​ 此处我们需要的值的目录为:计算机\\HKEY_LOCAL_MACHINE\\SOFTWARE\\Mozilla\\Mozilla Firefox\\67.0.4 (x64 zh-CN)\\Main,所以第一个参数为HKEY_LOCAL_MACHINE,第二个参数为SOFTWARE\\Mozilla\\Mozilla Firefox\\67.0.4 (x64 zh-CN)\\Main

​ 打开注册表之后,使用RegQueryValueEx()读取对应表项的值,函数的用法如下:

1
2
3
4
5
6
RegQueryValueEx(hKey,
TEXT("Install Directory"),
NULL,
NULL,
(LPBYTE)installPath,
&dwBuflen);

​ 第一个参数为之前函数返回的句柄。第二个参数为要查询的表项名,在这里应该是"Install Directory"。第三个参数是保留值,必须为NULL。第四个参数表示要读取的数据的类型,可为NULL。第五个参数表示接收返回值的缓冲区长度。第六个参数表示接收返回值的缓冲区地址。具体说明见MicrosoftDoc

代码实例及运行结果

​ 功能函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
//宏定义返回值以及特定参数
constexpr auto READ_FAIL = "read fail";//打开注册表失败
constexpr auto GET_FAIL = "get fail";//读取注册表失败或读取信息失败
constexpr auto MY_BUFSIZE = 256;//路径缓存空间大小

//获取Firefox的当前版本,输入为注册表中Mozilla Firefox的路径,返回值为失败信息或版本信息
string getCurrentVersion(string path) {
TCHAR currentVersion[MY_BUFSIZE];
HKEY hKey;
DWORD dwBuflen = MY_BUFSIZE;
LONG lRet;
memset(currentVersion, 0, (sizeof(currentVersion)));


lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
TEXT(path.c_str()),
0,
KEY_QUERY_VALUE | KEY_WOW64_64KEY,
&hKey);
if (lRet != ERROR_SUCCESS)return READ_FAIL;


lRet = RegQueryValueEx(hKey,
TEXT("CurrentVersion"),
NULL,
NULL,
(LPBYTE)currentVersion,
&dwBuflen);
if (lRet != ERROR_SUCCESS)return GET_FAIL;


RegCloseKey(hKey);
return currentVersion;
}

//获取Firefox的安装路径,返回值为获取失败的标记或安装路径
string getPath() {

TCHAR installPath[MY_BUFSIZE];
HKEY hKey;
memset(installPath, 0, sizeof(installPath));
DWORD dwBuflen = MY_BUFSIZE;
LONG lRet;
string tempPath = "SOFTWARE\\Mozilla\\Mozilla Firefox";

tempPath = tempPath + "\\" + getCurrentVersion(tempPath) + "\\Main";

lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
TEXT(tempPath.c_str()),
0,
KEY_QUERY_VALUE | KEY_WOW64_64KEY,
&hKey);
if (lRet != ERROR_SUCCESS)return READ_FAIL;


lRet = RegQueryValueEx(hKey,
TEXT("Install Directory"),
NULL,
NULL,
(LPBYTE)installPath,
&dwBuflen);
if (lRet != ERROR_SUCCESS)return GET_FAIL;


RegCloseKey(hKey);
return installPath;
}

​ 测试函数:

1
2
3
4
5
6
int main()
{
cout << getPath() << endl;

return 0;
}

​ 运行结果:

Result

​ 此处为了提高代码兼容性(兼容不同的Firefox版本),将路径获取分成了版本信息获取和路径获取两部分,其中SOFTWARE\\Mozilla\\Mozilla Firefox路径下的CurrentVersion表项存储当前的版本信息。

0%