TNSNames 读取器






1.67/5 (4投票s)
一篇文章,解释如何从 tnsnames.ora 文件中列出 Oracle 数据源。
引言
我需要一种方法让用户在一个应用程序中选择要使用的数据源。我们有多个数据库,这些数据库定义在 tnsnames.ora 文件中。本文展示了一个帮助你列出该文件中定义的数据源的类。我只是将代码从 VB 翻译过来,并在 这里 找到了一些修复。
类
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Win32;
using System.Text.RegularExpressions;
namespace TNSNamesReader
{
public class TNSNamesReader
{
public List<string> GetOracleHomes()
{
List<string> oracleHomes = new List<string>();
RegistryKey rgkLM = Registry.LocalMachine;
RegistryKey rgkAllHome = rgkLM.OpenSubKey(@"SOFTWARE\ORACLE");
if (rgkAllHome != null)
{
foreach (string subkey in rgkAllHome.GetSubKeyNames())
{
if (subkey.StartsWith("KEY_"))
oracleHomes.Add(subkey);
}
}
return oracleHomes;
}
private string GetOracleHomePath(String OracleHomeRegistryKey)
{
RegistryKey rgkLM = Registry.LocalMachine;
RegistryKey rgkOracleHome = rgkLM.OpenSubKey(@"SOFTWARE\ORACLE\" +
OracleHomeRegistryKey);
if (!rgkOracleHome.Equals(""))
return rgkOracleHome.GetValue("ORACLE_HOME").ToString();
return "";
}
private string GetTNSNAMESORAFilePath(String OracleHomeRegistryKey)
{
string oracleHomePath = this.GetOracleHomePath(OracleHomeRegistryKey);
string tnsNamesOraFilePath = "";
if (!oracleHomePath.Equals(""))
{
tnsNamesOraFilePath = oracleHomePath + @"\NETWORK\ADMIN\TNSNAMES.ORA";
if (!(System.IO.File.Exists(tnsNamesOraFilePath)))
{
tnsNamesOraFilePath = oracleHomePath + @"\NET80\ADMIN\TNSNAMES.ORA";
}
}
return tnsNamesOraFilePath;
}
public List<string> LoadTNSNames(string OracleHomeRegistryKey)
{
List<string> DBNamesCollection = new List<string>();
string RegExPattern = @"[\n][\s]*[^\(][a-zA-Z0-9_.]+[\s]*=[\s]*\(";
string strTNSNAMESORAFilePath = GetTNSNAMESORAFilePath(OracleHomeRegistryKey);
if (!strTNSNAMESORAFilePath.Equals(""))
{
//check out that file does physically exists
System.IO.FileInfo fiTNS = new System.IO.FileInfo(strTNSNAMESORAFilePath);
if (fiTNS.Exists)
{
if (fiTNS.Length > 0)
{
//read tnsnames.ora file
int iCount;
for (iCount = 0; iCount < Regex.Matches(
System.IO.File.ReadAllText(fiTNS.FullName),
RegExPattern).Count; iCount++)
{
DBNamesCollection.Add(Regex.Matches(
System.IO.File.ReadAllText(fiTNS.FullName),
RegExPattern)[iCount].Value.Trim().Substring(0,
Regex.Matches(System.IO.File.ReadAllText(fiTNS.FullName),
RegExPattern)[iCount].Value.Trim().IndexOf(" ")));
}
}
}
}
return DBNamesCollection;
}
}
}
Using the Code
- 在你的窗体中创建一个类的实例。
private TNSNamesReader tnsNamesReader = new TNSNamesReader();
- 填充一个列表控件(组合框、列表框等),让你的用户选择包含 tnsnames.ora 文件的 Oracle Home。
cmbOracleHome.DataSource = tnsNamesReader.GetOracleHomes();
- 使用找到的数据源填充另一个列表控件。
this.cmbDataSource.DataSource = tnsNamesReader.LoadTNSNames( (string)this.cmbOracleHome.SelectedValue);
关注点
在文章中我指出的,应该有一个注册表键“SOFTWARE\ORACLE\ALL_HOMES”和一个名为“LAST_HOME”的子键。我的注册表中都不存在,导致了异常。我查看了 Windows 注册表,发现每个 Oracle Home 注册表键都以“KEY_”开头,所以我获取了所有以这个词开头的键并将它们列为 Oracle Home。一旦选择了 Oracle Home,我们就可以查找 tnsnames.ora 文件的路径并加载其数据源。这个类无法找到当前或活动的 Oracle Home,但是你必须选择一个。