在最开始寻找Java路径使用的是vbs的方法,但是那个功能比较少,不能知道是否正确的打开了注册表,不能列遍注册表,不能查找64位注册表的内容
所以为了使程序能够正常的运行在各种系统上还是使用了这种办法。
API RegOpenKeyEx的参数以及使用方法 用来打开注册表项获得句柄,其他API都通过这个句柄对注册表进行操作。
还有一个RegOpenKey的API,和这个差不多,但是这个有一个PEGSAM samDesired的安全访问标记参数,如果此处填写为256则可以访问64位注册表。
LONG RegOpenKeyEx( HKEY hKey, // 需要打开的主键的名称 LPCTSTR lpSubKey, //需要打开的子键的名称 DWORD ulOptions, // 保留,设为0 REGSAM samDesired, // 安全访问标记,也就是权限 PHKEY phkResult // 得到的将要打开键的句柄 )
API RegEnumKeyEx 可以列遍某个项下的所有项 用来列遍出系统内安装的所有Java版本
RegEnumKeyEx 返回值 Long,零(ERROR_SUCCESS)表示成功。其他任何值都代表一个错误代码 hKey Long,一个已打开项的句柄,或者指定一个标准项名 dwIndex Long,欲获取的子项的索引。第一个子项的索引编号为零 lpName String,用于装载指定索引处项名的一个缓冲区 lpcbName Long,指定一个变量,用于装载lpName缓冲区的实际长度(包括空字符)。一旦返回,它会设为实际装载到lpName缓冲区的字符数量 lpReserved Long,未用,设为零 lpClass String,项使用的类名。可以为vbNullString lpcbClass Long,用于装载lpClass缓冲区长度的一个变量。一旦返回,它会设为实际装载到缓冲区的字符数量 lpftLastWriteTime FILETIME,枚举子项上一次修改的时间
API RegQueryValueEx 用来获取某个项下面的键值,获取Java路径时需要用到
RegQueryValueEx 返回值 Long,零(ERROR_SUCCESS)表示成功。其他任何值都代表一个错误代码 参数表 参数 类型及说明 HKEY hKey,//一个已打开项的句柄,或者指定一个标准项名 LPCTSTR lpValueName,//要查询注册表键值的名字字符串,注册表键的名字,以空字符结束。 LPDWORD lpReserved,//未用,设为零 LPDWORD lpType,//用于装载取回数据类型的一个变量 LPBYTE lpData,//用于装载指定值的一个缓冲区 LPDWORD lpcbData,//用于装载lpData缓冲区长度的一个变量。 //一旦返回,它会设为实际装载到缓冲区的字节数
findjavaM.bas模块
findjava(字符串数组) 最后这个字符串数组在其方法内被赋值
返回值整形 如果等于0则是没有找到系统内正确安装的Java
其中Sub main方法是调用演示
Option Explicit Public Enum EsystemBit x32 = 0 x64 = 1 End Enum '系统位数 Public systemBit As Integer '查找到的第一个java Public java_First As String '查找到的最后一个java Public java_Last As String Sub main() Dim javalist() As String 'findjava javalist Dim i As Integer If findjava(javalist) <> 0 Then For i = 0 To UBound(javalist) MsgBox javalist(i) Next i Else MsgBox "没查找到Java" End If End Sub Public Function findjava(javalist) As Integer Dim hKey As Long, Cnt As Long, sSave As String, i As Integer '打开32/64位注册表 If Dir(Environ("Windir") & "\sysWOW64", vbDirectory) <> "" Then If RegOpenKeyEx(KeyRoot.HKEY_LOCAL_MACHINE, "SOFTWARE\JavaSoft\Java Runtime Environment", 0, 256, hKey) <> 0 Then findjavaL = 0 systemBit = EsystemBit.x64 Exit Function Else systemBit = EsystemBit.x64 End If Else If RegOpenKeyEx(KeyRoot.HKEY_LOCAL_MACHINE, "SOFTWARE\JavaSoft\Java Runtime Environment", 0, 0, hKey) <> 0 Then findjavaL = 0 systemBit = EsystemBit.x32 Exit Function Else systemBit = EsystemBit.x32 End If End If Do sSave = String(255, 0) '列遍java版本列表 If RegEnumKeyEx(hKey, Cnt, sSave, 255, 0, vbNullString, ByVal 0, ByVal 0) <> 0 Then Exit Do '储存列表至数组 ReDim Preserve javalist(Cnt) javalist(Cnt) = StripTerminator(sSave) Debug.Print javalist(Cnt) Cnt = Cnt + 1 Loop RegCloseKey hKey Debug.Print UBound(javalist) findJavaHome javalist, javalist java_First = javalist(0) java_Last = javalist(UBound(javalist)) findjava = 1 End Function Private Function findJavaHome(javalist, rjavalist) Dim hKey As Long, Cnt As Long, sSave As String, i As Integer Dim keyValue As String, lenData As Long lenData = 1024 For i = 0 To UBound(javalist) '判断系统为数访问注册表 If systemBit = EsystemBit.x32 Then RegOpenKeyEx KeyRoot.HKEY_LOCAL_MACHINE, "SOFTWARE\JavaSoft\Java Runtime Environment\" & javalist(i), 0, 0, hKey Else RegOpenKeyEx KeyRoot.HKEY_LOCAL_MACHINE, "SOFTWARE\JavaSoft\Java Runtime Environment\" & javalist(i), 0, 256, hKey End If Dim ui As Integer '取出预留空间 keyValue = String(50, 0) RegQueryValueEx hKey, "JavaHome", 0&, 1&, keyValue, lenData javalist(i) = keyValue Debug.Print Cnt & keyValue RegCloseKey hKey Next i End Function Private Function StripTerminator(sInput As String) As String Dim ZeroPos As Integer '搜索第一个 Chr$(0) 中止符 ZeroPos = InStr(1, sInput, vbNullChar) If ZeroPos > 0 Then StripTerminator = Left$(sInput, ZeroPos - 1) Else StripTerminator = sInput End If End Function
RegeditAPI.bas 一个注册表操作的API声明模块,在网上也可以找到,但是在这里我稍作了修改
Option Explicit Option Compare Text Type FILETIME lLowDateTime As Long lHighDateTime As Long End Type '--------------------------------------------------------------- '- 注册表 API 声明... '--------------------------------------------------------------- Public Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long Public Declare Function RegCreateKeyEx Lib "advapi32.dll" Alias "RegCreateKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal Reserved As Long, ByVal lpClass As String, ByVal dwOptions As Long, ByVal samDesired As Long, lpSecurityAttributes As SECURITY_ATTRIBUTES, phkResult As Long, lpdwDisposition As Long) As Long Public Declare Function RegDeleteKey Lib "advapi32.dll" Alias "RegDeleteKeyA" (ByVal hKey As Long, ByVal lpSubKey As String) As Long Public Declare Function RegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueA" (ByVal hKey As Long, ByVal lpValueName As String) As Long Public Declare Function RegOpenKeyExA Lib "advapi32.dll" Alias "RegOpenKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long Public Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As Long) As Long Public Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, ByVal lpData As String, lpcbData As Long) As Long Public Declare Function RegRestoreKey Lib "advapi32.dll" Alias "RegRestoreKeyA" (ByVal hKey As Long, ByVal lpFile As String, ByVal dwFlags As Long) As Long Public Declare Function RegSaveKey Lib "advapi32.dll" Alias "RegSaveKeyA" (ByVal hKey As Long, ByVal lpFile As String, lpSecurityAttributes As SECURITY_ATTRIBUTES) As Long Public Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, lpData As Any, ByVal cbData As Long) As Long Public Declare Function RegQueryInfoKey Lib "advapi32.dll" Alias "RegQueryInfoKeyA" (ByVal hKey As Long, ByVal lpClass As String, lpcbClass As Long, ByVal lpReserved As Long, lpcSubKeys As Long, lpcbMaxSubKeyLen As Long, lpcbMaxClassLen As Long, lpcValues As Long, lpcbMaxValueNameLen As Long, lpcbMaxValueLen As Long, lpcbSecurityDescriptor As Long, lpftLastWriteTime As FILETIME) As Long Public Declare Function RegEnumValue Lib "advapi32.dll" Alias "RegEnumValueA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpValueName As String, lpcbValueName As Long, ByVal lpReserved As Long, lpType As Long, lpData As Byte, lpcbData As Long) As Long Public Declare Function RegEnumKeyEx Lib "advapi32.dll" Alias "RegEnumKeyExA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpName As String, lpcbName As Long, ByVal lpReserved As Long, ByVal lpClass As String, lpcbClass As Long, lpftLastWriteTime As Any) As Long Public Declare Function AdjustTokenPrivileges Lib "advapi32.dll" (ByVal TokenHandle As Long, ByVal DisableAllPriv As Long, NewState As TOKEN_PRIVILEGES, ByVal BufferLength As Long, PreviousState As TOKEN_PRIVILEGES, ReturnLength As Long) As Long 'Used to adjust your program's security privileges, can't restore without it! Public Declare Function LookupPrivilegeValue Lib "advapi32.dll" Alias "LookupPrivilegeValueA" (ByVal lpSystemName As Any, ByVal lpName As String, lpLuid As LUID) As Long 'Returns a valid LUID which is important when making security changes in NT. Public Declare Function OpenProcessToken Lib "advapi32.dll" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As Long Public Declare Function GetCurrentProcess Lib "kernel32" () As Long Public Declare Function RegCreateKey Lib "advapi32.dll" Alias "RegCreateKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long Public Declare Function RegQueryValueExA Lib "advapi32.dll" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, ByRef lpData As Long, lpcbData As Long) As Long Public Declare Function RegSetValueExA Lib "advapi32.dll" (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, ByRef lpData As Long, ByVal cbData As Long) As Long Public Declare Function RegSetValueExB Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, ByRef lpData As Byte, ByVal cbData As Long) As Long '--------------------------------------------------------------- '- 注册表 Api 常数... '--------------------------------------------------------------- ' 注册表创建类型值... Const REG_OPTION_NON_VOLATILE = 0 ' 当系统重新启动时,关键字被保留 ' 注册表关键字安全选项... Const READ_CONTROL = &H20000 Const KEY_QUERY_VALUE = &H1 Const KEY_SET_VALUE = &H2 Const KEY_CREATE_SUB_KEY = &H4 Const KEY_ENUMERATE_SUB_KEYS = &H8 Const KEY_NOTIFY = &H10 Const KEY_CREATE_LINK = &H20 Const KEY_READ = KEY_QUERY_VALUE + KEY_ENUMERATE_SUB_KEYS + KEY_NOTIFY + READ_CONTROL Const KEY_WRITE = KEY_SET_VALUE + KEY_CREATE_SUB_KEY + READ_CONTROL Const KEY_EXECUTE = KEY_READ Const KEY_ALL_ACCESS = KEY_QUERY_VALUE + KEY_SET_VALUE + KEY_CREATE_SUB_KEY + KEY_ENUMERATE_SUB_KEYS + KEY_NOTIFY + KEY_CREATE_LINK + READ_CONTROL Const KEY_WOW64_64KEY = &H100 + KEY_ALL_ACCESS Const ERROR_SUCCESS = 0& Const ERROR_BADDB = 1009& Const ERROR_BADKEY = 1010& Const ERROR_CANTOPEN = 1011& Const ERROR_CANTREAD = 1012& Const ERROR_CANTWRITE = 1013& Const ERROR_OUTOFMEMORY = 14& Const ERROR_INVALID_PARAMETER = 87& Const ERROR_ACCESS_DENIED = 5& Const ERROR_NO_MORE_ITEMS = 259& Const ERROR_MORE_DATA = 234& Const REG_NONE = 0& Const REG_DWORD_LITTLE_ENDIAN = 4& Const REG_DWORD_BIG_ENDIAN = 5& Const REG_LINK = 6& Const REG_RESOURCE_LIST = 8& Const REG_FULL_RESOURCE_DESCRIPTOR = 9& Const REG_RESOURCE_REQUIREMENTS_LIST = 10& Const WRITE_DAC = &H40000 Const WRITE_OWNER = &H80000 Const SYNCHRONIZE = &H100000 Const STANDARD_RIGHTS_REQUIRED = &HF0000 Const STANDARD_RIGHTS_READ = READ_CONTROL Const STANDARD_RIGHTS_WRITE = READ_CONTROL Const STANDARD_RIGHTS_EXECUTE = READ_CONTROL Dim hKey As Long, MainKeyHandle As Long Dim rtn As Long, lBuffer As Long, sBuffer As String Dim lBufferSize As Long Dim lDataSize As Long Dim ByteArray() As Byte ' 返回值... Const ERROR_NONE = 0 ' 有关导入/导出的常量 Const REG_FORCE_RESTORE As Long = 8& Const TOKEN_QUERY As Long = &H8& Const TOKEN_ADJUST_PRIVILEGES As Long = &H20& Const SE_PRIVILEGE_ENABLED As Long = &H2 Const SE_RESTORE_NAME = "SeRestorePrivilege" Const SE_BACKUP_NAME = "SeBackupPrivilege" '--------------------------------------------------------------- '- 注册表类型... '--------------------------------------------------------------- Private Type SECURITY_ATTRIBUTES nLength As Long lpSecurityDescriptor As Long bInheritHandle As Boolean End Type Private Type LUID lowpart As Long highpart As Long End Type Private Type LUID_AND_ATTRIBUTES pLuid As LUID Attributes As Long End Type Private Type TOKEN_PRIVILEGES PrivilegeCount As Long Privileges As LUID_AND_ATTRIBUTES End Type '--------------------------------------------------------------- '- 自定义枚举类型... '--------------------------------------------------------------- ' 注册表数据类型... Public Enum valuetype REG_SZ = 1 ' 字符串值 REG_EXPAND_SZ = 2 ' 可扩充字符串值 REG_BINARY = 3 ' 二进制值 REG_DWORD = 4 ' DWORD值 REG_MULTI_SZ = 7 ' 多字符串值 End Enum ' 注册表关键字根类型... Public Enum KeyRoot HKEY_CLASSES_ROOT = &H80000000 HKEY_CURRENT_USER = &H80000001 HKEY_LOCAL_MACHINE = &H80000002 HKEY_USERS = &H80000003 HKEY_PERFORMANCE_DATA = &H80000004 HKEY_CURRENT_CONFIG = &H80000005 HKEY_DYN_DATA = &H80000006 End Enum