2010-01-05 102 views
7

獲取tnsnames.ora文件的位置我如何通過代碼獲得tnsnames.ora文件的位置,在與Oracle客戶端機器上安裝?通過代碼

是否顯示該文件的位置的Windows註冊表鍵?

+0

你意識到'編程'意味着'按代碼,對吧? – 2010-01-05 14:27:38

+0

@George我正在尋找一個解決方案,不一定基於Windows註冊表,因爲再次編輯該問題。 – RRUZ 2010-01-05 14:46:37

回答

10

幾年前我有同樣的問題。
那時候我不得不支持Oracle 9和10,所以代碼只處理這些版本,但也許可以讓你免於某些研究。 的想法是:

  • 搜索註冊表,以確定Oracle客戶端版本
  • 試圖找到ORACLE_HOME
  • 終於從家裏TNSNAMES

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看起來是一個合理的開始。當然,迎合非標準安裝和各種解決方案以及像Instant Client這樣的東西可能會給你灰色頭髮。 – 2010-01-05 13:58:30

+0

雖然你應該嘗試在GetOracleHome()的註冊表之前使用環境變量。 – 2010-01-05 14:00:19

+0

謝天謝地,我不再需要跟Oracle一起追趕,因爲別人現在正在維護這些代碼:)但是在查詢註冊表之前檢查環境聽起來不錯。 – 2010-01-05 14:08:57

0

據取決於Oracle版本和SQL * Plus製程的工作目錄下網。 This first link告訴您指定Oracle的某些版本(7,8,9i)的基本路徑的環境變量。如果你使用不同的,我相信有一個類似的方式來到系統目錄。

如果您將這些文件的版本遍佈整個地方,並依賴於客戶端的「查找本地tnsnames.ora第一個」行爲,那麼我認爲您運氣不佳。

+0

該鏈接已過時,但行爲與最新版本(11g)一致。 – 2010-01-05 13:40:59

7

在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文件(第二次在這種情況下)。 LDAPHOSTNAME是解決數據庫的替代方法。如果沒有TNSNAMES,則TNSNAMES.ora文件如果存在於正確的位置將被忽略。

在C#/。NET這應該讓你的環境變量:

Environment.GetEnvironmentVariable("ORACLE_HOME");

Environment.GetEnvironmentVariable("TNS_ADMIN");

+0

@Colin,不幸的是,這些變量並不總是由oracle客戶端設置的。我正在使用oracle 11g。 – RRUZ 2010-01-05 13:41:46

+0

您是使用即時客戶端還是普通客戶端? – 2010-01-05 13:47:39

+0

我相信即時客戶端默認情況下不會創建%ORACLE_HOME%或tnsnames.ora – 2010-01-05 13:49:12

0

我不是一個C#或Windows人對於這個問題,所以希望這會有所幫助。 tnsnames.ora文件應位於:

ORACLE_HOME\network\admin 

如果已指定備用位置,它應該是通過TNS_ADMIN註冊表項可用。

對Windows上的Oracle如何處理TNS名稱的詳細信息請參見本link

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

這列出* tnsnames.ora的每個*副本。它沒有顯示哪一個正在使用。 – 2010-01-05 13:40:02

+1

你沒有指定... – GxG 2010-01-05 13:55:18

+0

不是我的問題,但你是對的,目前尚不清楚。在實踐中,確定使用哪個tnsnames.ora通常很重要,但我認爲你的回答仍然是一個有用的貢獻,我補充說明,所以我已經給你一個積極的反擊你收到的惡意軟件。 – 2010-01-07 10:05:36