Получение местоположения файла tnsnames.ora кодом

Как я могу получить местоположение tnsnames.ora файл кодом, в машине с установленным клиентом Oracle?

Существует ли ключ реестра окон, указывающий на местоположение этого файла?

7
задан RRUZ 5 January 2010 в 14:24
поделиться

5 ответов

Несколько лет назад у меня была такая же проблема.
Тогда мне пришлось поддерживать Oracle 9 и 10, так что код заботится только об этих версиях, но, возможно, он спасает вас от некоторых исследований. Идея заключается в следующем:

  • поиск в реестре для определения версии клиента Oracle
  • попытка найти ORACLE_HOME
  • наконец-то получить tnsnames от HOME

public enum OracleVersion
{
    Oracle9,
    Oracle10,
    Oracle0
};

private OracleVersion GetOracleVersion()
{
    RegistryKey rgkLM = Registry.LocalMachine;
    RegistryKey rgkAllHome = rgkLM.OpenSubKey(@"SOFTWARE\ORACLE\ALL_HOMES");

    /* 
     * 10g Installationen don't have an ALL_HOMES key
     * Try to find HOME at SOFTWARE\ORACLE\
     * 10g homes start with KEY_
     */
    string[] okeys = rgkLM.OpenSubKey(@"SOFTWARE\ORACLE").GetSubKeyNames();
    foreach (string okey in okeys)
    {
        if (okey.StartsWith("KEY_"))
            return OracleVersion.Oracle10;
    }

    if (rgkAllHome != null)
    {
        string strLastHome = "";
        object objLastHome = rgkAllHome.GetValue("LAST_HOME");
        strLastHome = objLastHome.ToString();
        RegistryKey rgkActualHome = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\ORACLE\HOME" + strLastHome);
        string strOraHome = "";
        object objOraHome = rgkActualHome.GetValue("ORACLE_HOME");
        string strOracleHome = strOraHome = objOraHome.ToString();
        return OracleVersion.Oracle9;
    }
    return OracleVersion.Oracle0;
}

private string GetOracleHome()
{
    RegistryKey rgkLM = Registry.LocalMachine;
    RegistryKey rgkAllHome = rgkLM.OpenSubKey(@"SOFTWARE\ORACLE\ALL_HOMES");
    OracleVersion ov = this.GetOracleVersion();

    switch(ov)
    {
        case OracleVersion.Oracle10:
            {
                string[] okeys = rgkLM.OpenSubKey(@"SOFTWARE\ORACLE").GetSubKeyNames();
                foreach (string okey in okeys)
                {
                    if (okey.StartsWith("KEY_"))
                    {
                        return rgkLM.OpenSubKey(@"SOFTWARE\ORACLE\" + okey).GetValue("ORACLE_HOME") as string;
                    }
                }
                throw new Exception("No Oracle Home found");
            }
        case OracleVersion.Oracle9:
            {
                string strLastHome = "";
                object objLastHome = rgkAllHome.GetValue("LAST_HOME");
                strLastHome = objLastHome.ToString();
                RegistryKey rgkActualHome = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\ORACLE\HOME" + strLastHome);
                string strOraHome = "";
                object objOraHome = rgkActualHome.GetValue("ORACLE_HOME");
                string strOracleHome = strOraHome = objOraHome.ToString();
                return strOraHome;
            }
        default:
            {
                throw new Exception("No supported Oracle Installation found");
            }
    }
}

public string GetTNSNAMESORAFilePath()
{
    string strOracleHome = GetOracleHome();
    if (strOracleHome != "")
    {
        string strTNSNAMESORAFilePath = strOracleHome + @"\NETWORK\ADMIN\TNSNAMES.ORA";
        if (File.Exists(strTNSNAMESORAFilePath))
        {
            return strTNSNAMESORAFilePath;
        }
        else
        {
            strTNSNAMESORAFilePath = strOracleHome + @"\NET80\ADMIN\TNSNAMES.ORA";
            if (File.Exists(strTNSNAMESORAFilePath))
            {
                return strTNSNAMESORAFilePath;
            }
            else
            {
                throw new SystemException("Could not find tnsnames.ora");
            }
        }
    }
    else
    {
        throw new SystemException("Could not determine ORAHOME");
    }
}
10
ответ дан 6 December 2019 в 10:00
поделиться

В Windows наиболее вероятными местами являются %ORACLE_HOME%/network/admin или %TNS_ADMIN% (или настройка реестра TNS_ADMIN). Эти два параметра охватывают почти каждую установку.

Конечно, можно иметь работающего клиента Oracle и без этого файла. Oracle имеет завораживающий массив сетевых опций, и существует множество способов достижения рабочей установки с использованием TNSNAMES. В зависимости от того, что вы пытаетесь здесь сделать, вашим первым портом вызова может быть sqlnet.ora файл, который также находится в %ORACLE_HOME%/network/admin. Она должна содержать строку, которая выглядит следующим образом:

NAMES.DIRECTORY_PATH= (LDAP, TNSNAMES, HOSTNAME)

TNSNAMES означает, что он будет использовать файл TNSNAMES.ora (второй в данном случае). LDAP и HOSTNAME являются альтернативными способами разрешения базы данных. Если отсутствует TNSNAMES, то файл TNSNAMES.ora будет проигнорирован, если он существует в нужном месте.

В C# / . NET вам будут доступны переменные окружения:

Environment.GetEnvironmentVariable("ORACLE_HOME");

Environment.GetEnvironmentVariable("TNS_ADMIN");

7
ответ дан 6 December 2019 в 10:00
поделиться

В соответствии с сетью, которая зависит от версии Oracle и рабочей директории SQL*Plus процесса. Эта первая ссылка сообщает переменную окружения, которая определяет базовый путь для некоторых версий (7, 8, 9i) Oracle. Если вы используете другую, я уверен, что есть похожий способ попасть в системный каталог.

Если вы распространяете версии этих файлов повсюду и полагаетесь на поведение клиента "ищите сначала локальный tnsnames.ora", то, думаю, вам не повезло.

.
0
ответ дан 6 December 2019 в 10:00
поделиться
List<string> logicalDrives = Directory.GetLogicalDrives().ToList();
            List<string> result = new List<string>();
            foreach (string drive in logicalDrives)
            {
                Console.WriteLine("Searching " + drive);
                DriveInfo di = new DriveInfo(drive);
                if(di.IsReady)
                    result = Directory.GetFiles(drive, "tnsnames.ora", SearchOption.AllDirectories).ToList();
                if (0 < result.Count) return;
            }
            foreach (string file in result) { Console.WriteLine(result); }
.
2
ответ дан 6 December 2019 в 10:00
поделиться

Я не C# и не парень из Windows, так что надеюсь, это поможет. Файл tnsnames.ora должен находиться в:

ORACLE_HOME\network\admin

Если указано альтернативное местоположение, то оно должно быть доступно через ключ реестра TNS_ADMIN.

Смотрите эту ссылку для получения дополнительной информации о том, как Oracle обрабатывает имена tns в Windows.

0
ответ дан 6 December 2019 в 10:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: