Pergunta

Como posso obter a localização do arquivo tnsnames.ora por código, em uma máquina com o cliente Oracle instalado?

Existe um Windows Registry chave indicando o local desse arquivo?

Foi útil?

Solução

Alguns anos atrás eu tive o mesmo problema.
Naquela época eu tinha que suportar o Oracle 9 e 10 de modo que o código só cuida dessas versões, mas talvez ele evita que você alguma pesquisa. A idéia é:

  • procurar o registo para determinar a versão do cliente do Oracle
  • tentar encontrar o ORACLE_HOME
  • finalmente obter as tnsnames a partir de casa

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");
    }
}

Outras dicas

No Windows, os locais mais prováveis ??são ou %ORACLE_HOME%/network/admin ou %TNS_ADMIN% (ou a definição de registo TNS_ADMIN). Estes dois cobertura de quase todos os instalação.

Claro que é possível ter um cliente Oracle trabalhar sem este arquivo. A Oracle tem desconcertante variedade de opções de rede, e há muitas maneiras de alcançar uma configuração de trabalho com o uso de TNSNAMES. Dependendo do que você está tentando conseguir aqui, o seu primeiro porto de escala pode ser o arquivo sqlnet.ora, que também é encontrado em %ORACLE_HOME%/network/admin. Este deve conter uma linha que é algo como isto:

NAMES.DIRECTORY_PATH= (LDAP, TNSNAMES, HOSTNAME)

TNSNAMES significa que ele irá usar o arquivo TNSNAMES.ora (segunda, neste caso). LDAP e HOSTNAME são formas alternativas de resolução de banco de dados. Se não houver TNSNAMES o arquivo TNSNAMES.ora será ignorado se ele existe no lugar certo.

Em C # / .NET Isto deve dar para as variáveis ??de ambiente:

Environment.GetEnvironmentVariable("ORACLE_HOME");

Environment.GetEnvironmentVariable("TNS_ADMIN");

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); }

De acordo com a rede que depende da versão do Oracle e o diretório de trabalho do SQL * Plus processo. Este primeiro elo diz-lhe o variável de ambiente que especifica o caminho de base para algumas versões (7, 8, 9a) da Oracle. Se você usar um diferente, eu tenho certeza que há uma maneira similar para chegar ao diretório do sistema.

Se você espalhar versões desses arquivos em todo o lugar embora e contar com a "olhar para uma tnsnames.ora local primeiro" comportamento do cliente, então eu acho que você está sem sorte.

Eu não sou um C # ou um cara do Windows para que o assunto por isso espero que isso ajude. O arquivo tnsnames.ora deve estar localizado em:

ORACLE_HOME\network\admin

Se um local alternativo foi especificado, ele deve estar disponível através da chave de registro TNS_ADMIN.

Veja este ligação para obter mais informações sobre como a Oracle lida com tns nomes no Windows.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top