2010-01-05 6 views
7

Comment obtenir l'emplacement du fichier tnsnames.ora par code, sur une machine où le client Oracle est installé?Comment localiser le fichier tnsnames.ora par le code

Y at-il une clé de registre Windows indiquant l'emplacement de ce fichier?

+0

Vous se rendre compte que «par programme» signifie «par code, non? –

+0

@George Je suis à la recherche d'une solution, pas nécessairement basée sur le registre de Windows, à cause de cela modifier à nouveau la question. – RRUZ

Répondre

10

Il ya quelques années, j'ai eu le même problème.
Retour alors je dû soutenir Oracle 9 et 10 de sorte que le code ne prend soin de ces versions, mais peut-être il vous évite de quelques recherches. L'idée est de:

  • recherche le Registre pour déterminer la version du client Oracle
  • essayer de trouver les ORACLE_HOME
  • enfin obtenir les tnsnames de 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"); 
    } 
} 
+0

+1 semble être un bon point de départ. Bien sûr, la prise en charge des installations non standard et des diverses options de résolution ainsi que des choses comme le client instantané vous donneront probablement des cheveux gris. –

+0

Vous devriez essayer et utiliser les variables d'environnement avant le registre dans GetOracleHome() si. –

+0

Heureusement, je n'ai plus besoin de jouer au rattrapage avec Oracle car quelqu'un d'autre maintient ce code maintenant :) Mais vérifier l'environnement avant d'interroger le registre semble bien. –

0

Selon le réseau qui dépend de la version d'Oracle et du répertoire de travail du processus SQL * Plus. This first link vous indique la variable d'environnement qui spécifie le chemin de base pour certaines versions (7, 8, 9i) d'Oracle. Si vous en utilisez un autre, je suis sûr qu'il existe une façon similaire d'accéder au répertoire système.

Si vous diffusez des versions de ces fichiers partout et que vous vous basez sur le comportement "Rechercher un tnsnames local d'abord" du client, alors je suppose que vous n'avez pas de chance.

+0

Ce lien est un peu obsolète, mais le comportement est à peu près le même tout au long de la dernière version (11g). –

7

Sous Windows, les emplacements les plus probables sont %ORACLE_HOME%/network/admin ou %TNS_ADMIN% (ou le paramètre de registre TNS_ADMIN). Ces deux couvrent presque toutes les installations.

Bien sûr, il est possible d'avoir un client Oracle fonctionnel sans ce fichier. Oracle dispose d'une panoplie d'options de mise en réseau déconcertantes, et il existe de nombreuses façons d'obtenir une configuration fonctionnelle en utilisant TNSNAMES. Selon ce que vous essayez d'atteindre ici, votre premier port d'escale pourrait être le fichier sqlnet.ora, qui se trouve aussi dans %ORACLE_HOME%/network/admin. Cela devrait contenir une ligne qui ressemble à quelque chose comme ceci:

NAMES.DIRECTORY_PATH= (LDAP, TNSNAMES, HOSTNAME) 

TNSNAMES signifie qu'il utilisera le fichier TNSNAMES.ora (deuxième dans ce cas). LDAP et HOSTNAME sont d'autres façons de résoudre la base de données. S'il n'y a pas TNSNAMES le fichier TNSNAMES.ora sera ignoré s'il existe au bon endroit.

En C#/.NET ce que vous devriez obtenir les variables d'environnement:

Environment.GetEnvironmentVariable("ORACLE_HOME");

Environment.GetEnvironmentVariable("TNS_ADMIN");

+0

@Colin, Malheureusement, ces variables ne sont pas toujours définies par le client Oracle. J'utilise Oracle 11g. – RRUZ

+0

Utilisez-vous le client instantané ou le client régulier? –

+0

Je crois que le client instantané ne crée pas% ORACLE_HOME% ou tnsnames.ora par défaut –

0

Je ne suis pas un C# ou un gars Windows pour cette question si nous espérons que cela aide. Le fichier tnsnames.ora doit être situé dans:

ORACLE_HOME\network\admin 

Si un autre emplacement a été spécifié, il devrait être disponible via la clé de Registre TNS_ADMIN.

Voir ce link pour plus d'informations sur la façon dont Oracle gère les noms tns sous Windows.

2
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); } 
+3

Ceci liste * chaque * copie de tnsnames.ora. Il ne montre pas lequel est en cours d'utilisation. –

+1

vous n'avez pas précisé que ... – GxG

+0

Pas ma question, mais vous avez raison, ce n'est pas clair. En pratique, déterminer quel tnsnames.ora est utilisé est normalement important, mais je pensais que votre réponse était toujours une contribution utile, avec la mise en garde que j'ai ajouté, donc je vous ai donné un upvote pour contrer le downvote que vous avez reçu. –

Questions connexes