Pregunta

¿Cómo puedo obtener la ubicación del archivo tnsnames.ora por código, en una máquina con el cliente de Oracle instalado?

¿Hay una clave de registro de Windows que indica la ubicación de este archivo?

¿Fue útil?

Solución

Hace algunos años tuve el mismo problema.
En aquel entonces yo tenía que soportar Oracle 9 y 10 por lo que el código sólo se encarga de esas versiones, pero tal vez le ahorra un poco de investigación. La idea es:

  • buscar el registro para determinar la versión del cliente de Oracle
  • tratar de encontrar el ORACLE_HOME
  • finalmente obtener los tnsnames desde 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");
    }
}

Otros consejos

En Windows, los lugares más probables son bien %ORACLE_HOME%/network/admin o %TNS_ADMIN% (o la configuración del registro TNS_ADMIN). Estos dos cubren casi cada instalación.

Por supuesto que es posible tener un cliente de Oracle trabaja sin este archivo. Oracle tiene desconcertante variedad de opciones de red, y hay un montón de maneras de lograr una configuración de trabajo con el uso de TNSNAMES. Dependiendo de lo que está tratando de lograr aquí, su primer punto de contacto podría ser el archivo sqlnet.ora, que también se encuentra en %ORACLE_HOME%/network/admin. Esto debe contener una línea que se ve algo como esto:

NAMES.DIRECTORY_PATH= (LDAP, TNSNAMES, HOSTNAME)

TNSNAMES significa que va a utilizar el archivo TNSNAMES.ora (segundo en este caso). LDAP y HOSTNAME son formas alternativas de resolución de la base de datos. Si no hay TNSNAMES el archivo TNSNAMES.ora se tendrá en cuenta si es que existe en el lugar correcto.

En C # / .NET esto debe conseguir que las variables de entorno:

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 acuerdo con la red que depende de la versión de Oracle y el directorio de trabajo del proceso de SQL * Plus. Este primer enlace que la cuenta variable de entorno que especifica la ruta de la base para algunas versiones (7, 8, 9i) de Oracle. Si utiliza una diferente, estoy seguro de que hay una manera similar para obtener el directorio del sistema.

Si usted separa versiones de estos archivos por todo el lugar sin embargo y se basan en el comportamiento de "buscar un tnsnames.ora local en primer lugar" del cliente, entonces supongo que está de suerte.

No soy un C # o un tipo de Windows para el caso, así que espero que esto ayude. El archivo tnsnames.ora debe estar ubicado en:

ORACLE_HOME\network\admin

Si se ha especificado una ubicación alternativa, que debería estar disponible a través de la clave de registro TNS_ADMIN.

enlace para obtener más información sobre cómo maneja Oracle TNS nombres en Windows.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top