WINDOWS下操作注册表 REG_EXPAND_SZ与REG_SZ的区别
在WINDOWS下开发ORACLE程序,需要安装ORACLE的CLIENT.
这个东东比较大.几百M.好在到10后 ORACLE推出了一个INSTANT CLIENT
几十M搞定.这下方便了..可以直接打包.不过,要注册三个变量. TNS_ADMIN NLS_LANG PATH
这中间,遇到两上问题..搞了一晚上.也真是WINDOWS下开发没经验..活该郁闷...
1.注册表操作
为了自动设置这三个变量...写了一小段程序.如下
1 int get_app_path(char *path)
2 {
3 char buff[MAX_PATH];
4
5 memset(buff, 0, sizeof(buff));
6 if (GetModuleFileName(NULL, buff, MAX_PATH) == 0)
7 {
8 return -1;
9 }
10 memcpy(path, buff, strlen(buff));
11
12 return 0;
13 }
14
15 int reg_ora_client(const char *path)
16 {
17 HKEY hreg;
18 char dir[MAX_PATH];
19 char paths[4096];
20 unsigned long size, len;
21
22 if (path == NULL || (len = strlen(path)) < 2)
23 {
24 return -1;
25 }
26
27 len --;
28 memset(dir, 0, sizeof(dir));
29 strcpy(dir, path);
30
31 while (dir[len] == '\\')
32 {
33 dir[len --] = 0;
34 }
35
36 if(RegOpenKey(HKEY_LOCAL_MACHINE, \
37 "SYSTEM\\ControlSet001\\Control\\Session Manager\\Environment", \
38 &hreg) != ERROR_SUCCESS)
39 {
40 fprintf(stderr, "设置ORACLE环境 --- 无法打开键!\n");
41 return -1;
42 }
43
44 if (RegSetValueEx(hreg, "TNS_ADMIN", 0, REG_SZ, \
45 (const unsigned char *)dir, strlen(dir)) != ERROR_SUCCESS)
46 {
47 fprintf(stderr, "设置ORACLE环境 --- 无法设置TNS_ADMIN!\n");
48 RegCloseKey(hreg);
49 return -1;
50 }
51
52 size = 4096;
53 memset(paths, 0, sizeof(paths));
54
55 if (RegQueryValueEx(hreg, "PATH", NULL, NULL, (unsigned char *)paths, &size) != ERROR_SUCCESS)
56 {
57 RegCloseKey(hreg);
58 return -1;
59 }
60
61 if (stristr(paths, dir) == NULL)
62 {
63 len = strlen(paths);
64
65 if (paths[-- len] != ';')
66 {
67 strcat(paths, ";");
68 }
69
70 strcat(paths, dir);
71
72 if (RegSetValueEx(hreg, "PATH", 0, REG_EXPAND_SZ, \
73 (const unsigned char *)paths, strlen(paths)) != ERROR_SUCCESS)
74 {
75 fprintf(stderr, "设置ORACLE环境 --- 无法设置PATH!\n");
76 RegCloseKey(hreg);
77 return -1;
78 }
79 }
80
81 if (RegSetValueEx(hreg, "NLS_LANG", 0, REG_SZ, \
82 (const unsigned char *)"SIMPLIFIED CHINESE_CHINA.ZHS16GBK", 33) != ERROR_SUCCESS)
83 {
84 fprintf(stderr, "设置ORACLE环境 --- 无法设置NLS_LANG!\n");
85 RegCloseKey(hreg);
86 return -1;
87 }
88
89 RegCloseKey(hreg);
90 return 0;
91 }
92
93
94 int rdb_init()
95 {
96 char dir[MAX_PATH];
97 char *p;
98
99 memset(dir, 0, sizeof(dir));
100
101 if (get_app_path(dir) == -1)
102 {
103 return -1;
104 }
105
106 if ((p = strrchr(dir, '\\')) == NULL)
107 {
108 return -1;
109 }
110
111 memset(p, 0, sizeof(dir) - (p - dir));
112
113 if (reg_ora_client(dir) == -1)
114 {
115 return -1;
116 }
117
118 return 0;
119 }
这里面有一个宏为REG_EXPAND_SZ
开始,我用的是REG_SZ...结果运行一次之后,VS2005不能编译了..报什么 生成 "cmd.exe"失败
我晕倒...然后以为是VS2005出问题了...开始拿着报的错在网上狂找.
于是不停的重启,重置环境变量,重写程序,放前面,放后面.放中间................
过了很久. 我在CMD里奇怪的发现 PATH指令后输出的东西没有替换
正常的为:
PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;D:\CodeBlocks-10.05\MinGW\bin
而运行程序后变成了:
PATH=%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;D:\CodeBlocks-10.05\MinGW\bin
于是觉得问题不是出在VS2005上..应该跟我动过注册表有关.
最后还是从CSDN论坛上搜到一个答案..
值类型为REG_EXPAND_SZ时,表明这是一个扩展字符串,可被替换..否则 不能被替换...
把程序里改为REG_EXPAND_SZ.....一切正常..
2. 所用INSTANT CLIENT版本为 instantclient-basic-win32-10.2.0.4.zip
看了下,有个更小的..说什么,提供最基本的运行时...一时高兴下之(我不用SQLPLUS)instantclient-basiclite-win32-10.2.0.4.zip
两个包,里面主要差别在一个DLL上.当然了,大的包括的肯定多一些,小的少一些.
我不用其它功能,当然是用小的了...从没有想过,ORACLE提供的东西,也可能不对..........................
开始不停的报错..找了好久..涉及前面注册表那个问题...乱在了一起...
等注册表搞定后..换了几个DLL...发现..大的好用..一换成小的..就报什么VS2005的运行时错..
猜可能的原因.. 1ORACLE提供的DLL是用其它版本的VS出来的. 2需要更多的环境变量来描述它. 3还是自己菜
不管怎么样..大就大点吧...能过就行...呵呵