问题
In a previous post, I was working on using VBS to list all of the drivers installed on a machine. I am particularily interested in the Oracle drivers.
Now, I'd like to next capture the contents of the applicable tnsnames.ora files. In practice in our environment, I would expect up to 3 tnsnames.ora fuiles with the assumption that a machine might have both the 32 bit and 64 bit drivers installed. I would then expect 1 tnnamesora file in the 32 bit admin folder, 1 in the 63 bit folder and one in the %TNS_ADMIN% folder, if there is a system variable defined for %TNS_ADMIN%. On my machine, my %TNS_ADMIN% system variable is set to C:\Windows\TNS and once set, I need not have a separate tbnsnames.ora file in the 32 and 64 bit locations. The one in the %TNS_ADMIN% location if defined, will be used by eiether driver. On my PC the 32 and 64 bit tnsnames.ora file locations are :
C:\Oracle\product\11203_32bit\CLIENT_1\NETWORK\ADMIN
C:\Oracle\product\11203_64bit\CLIENT_1\NETWORK\ADMIN
What I would like to do is to identify these locations using VBS to read the registry and then use the TYPE command on each file to echo the contents to the console using the code of my previous post as a starting point.
I've been poking around in the registry trying to find the relevant keys or chain of keys to get this info. With that info, I may be able to figure out the code.. Thanks.
REM Run this file with the following command:
REM cscript ListDriversV2.vbs | clip
WScript.Echo "------------------------------------------------"
'Get Server Name
Set wshNetwork = WScript.CreateObject( "WScript.Network" )
strComputerName = wshNetwork.ComputerName
WScript.Echo "Computer Name: " & strComputerName
'List 64 bit drivers
WScript.Echo "------------------------------------------------"
WScript.Echo "List 64 bit drivers:"
WScript.Echo
Const HKEY_LOCAL_MACHINE = &H80000002
strComputer = "."
Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")
strKeyPath = "SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers"
objRegistry.EnumValues HKEY_LOCAL_MACHINE, strKeyPath, arrValueNames, arrValueTypes
For i = 0 to UBound(arrValueNames)
strValueName = arrValueNames(i)
objRegistry.GetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
Wscript.Echo arrValueNames(i) & " -- 64 Bit " & strValue
Next
'List 32 bit drivers
WScript.Echo "------------------------------------------------"
WScript.Echo "List 32 bit drivers:"
WScript.Echo
strKeyPath = "SOFTWARE\Wow6432Node\ODBC\ODBCINST.INI\ODBC Drivers"
objRegistry.EnumValues HKEY_LOCAL_MACHINE, strKeyPath, arrValueNames, arrValueTypes
For i = 0 to UBound(arrValueNames)
strValueName = arrValueNames(i)
objRegistry.GetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
Wscript.Echo arrValueNames(i) & " -- 32 Bit " & strValue
Next
'List Oracle Environment variables
WScript.Echo "------------------------------------------------"
WScript.Echo "List Oracle Environment variables:"
WScript.Echo
Set objShell = WScript.CreateObject("WScript.Shell")
strTnsAdmin = objShell.Environment("SYSTEM").Item("TNS_ADMIN")
WScript.Echo "TNS_ADMIN=" & strTnsAdmin
strOracleHome = objShell.Environment("SYSTEM").Item("ORACLE_HOME")
WScript.Echo "ORACLE_HOME=" & stroracleHome
WScript.Echo "------------------------------------------------"
WScript.Echo "List All System Environment variables:"
WScript.Echo
Set objEnv = objShell.Environment("SYSTEM")
For Each strVar in objEnv
WScript.Echo strVar
Next
WScript.Echo "------------------------------------------------"
WScript.Echo "List All User Environment variables:"
WScript.Echo
Set objEnv = objShell.Environment("User")
For Each strVar in objEnv
WScript.Echo strVar
Next
WScript.Echo "------------------------------------------------"
'How do I dynamically determine this Oracle 64 bit tnsnames location location from the registry?
strPath = "E:\oracle_12101_64bit\product\12101_64bit\CLIENT_1\NETWORK\ADMIN\"
WScript.Echo "Dump " & strPath
WScript.Echo
strFileContent = LoadStringFromFile(strPath)
WScript.Echo LoadStringFromFile(strPath)
WScript.Echo strPath
WScript.Echo "------------------------------------------------"
'How do I dynamically determine this Oracle 32 bit tnsnames location location from the registry?
strPath = "E:\Oracle\product\11.2.0\client_32Bit\NETWORK\ADMIN\TNSNAMES.ORA"
WScript.Echo "Dump " & strPath
WScript.Echo
strFileContent = LoadStringFromFile(strPath)
WScript.Echo LoadStringFromFile(strPath)
WScript.Echo strPath
WScript.Echo "------------------------------------------------"
strPath = strTnsAdmin & "\tnsnames.ora"
WScript.Echo "Dump " & strPath
WScript.Echo
strFileContent = LoadStringFromFile(strPath)
WScript.Echo LoadStringFromFile(strPath)
WScript.Echo strPath
Function LoadStringFromFile(filename)
Const fsoForReading = 1
Const fsoForWriting = 2
Dim fso, f
Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FileExists(filename) Then
Set f = fso.OpenTextFile(filename, fsoForReading)
LoadStringFromFile = f.ReadAll
f.Close
Else
LoadStringFromFile = ""
End if
End Function
回答1:
According Oracle these locations are searched for tnsnames.ora, resp. sqlnet.ora:
- current path (associated with the running client application)
- Environment variable
TNS_ADMINdefined for the session - Environment variable
TNS_ADMINdefined for the system - Windows Registry Key
HKLM\SOFTWARE\ORACLE\KEY_{ORACLE_HOME_NAME}\TNS_ADMIN(for 64 bit) orHKLM\SOFTWARE\Wow6432Node\ORACLE\KEY_{ORACLE_HOME_NAME}\TNS_ADMIN(for 32 bit) %ORACLE_HOME%\network\admin
However, I am not sure whether each application/driver/version follows this list. This list was provided by Oracle related to version 9i. I think you will manage it to query these folders by VBScript.
If ORACLE_HOME is not set by Environment variable, you have to query the Registry HKLM\SOFTWARE\ORACLE\KEY_{ORACLE_HOME_NAME}\ORACLE_HOME (for 64 bit) or HKLM\SOFTWARE\Wow6432Node\ORACLE\KEY_{ORACLE_HOME_NAME}\ORACLE_HOME (for 32 bit)
For ORACLE_HOME_NAME you have to navigate to your Oracle bin folder (to be found via %PATH% Environment variable) and open file oracle.key. This is a simple text file containing only the ORACLE_HOME_NAME value, e.g. OraClient11g_home1.
However, typically there is only one Oracle Home underneath HKLM\SOFTWARE\ORACLE, so seeking and reading file oracle.key might be an overkill.
Update
When I run a test on my machine (with Oracle Client 11.2) I get following order:
- Environment variable
TNS_ADMIN HKLM\SOFTWARE\ORACLE\KEY_{Oracle_Home_Name}\TNS_ADMIN, resp.HKLM\SOFTWARE\Wow6432Node\ORACLE\KEY_{Oracle_Home_Name}\TNS_ADMIN-> Only ifTNS_ADMINEnvironment variable is not set.%ORACLE_HOME%\network\admin- Current directory (which can be different to directory where your application is located)
- Folder where your application is located
For a deep analysis you have to search for tnsnames.ora, sqlnet.ora and ldap.ora. The Oracle database name can be resolved through each of them, i.e. a connection may be established even when tnsnames.ora and sqlnet.ora do not exist.
来源:https://stackoverflow.com/questions/28326892/identifying-the-location-of-the-relevant-tnsnames-and-echoing-to-the-console