2010-01-05 38 views
7

Làm cách nào để có được vị trí của tệp tnsnames.ora theo mã, trong một máy có cài đặt ứng dụng khách Oracle?Nhận vị trí của tệp tnsnames.ora theo mã

Có khoá đăng ký cửa sổ cho biết vị trí của tệp này không?

+0

Bạn nhận ra rằng 'Lập trình' có nghĩa là 'Theo Mã, đúng không? –

+0

@George Tôi đang tìm kiếm một giải pháp, không nhất thiết phải dựa trên các cửa sổ đăng ký, do đó chỉnh sửa lại câu hỏi. – RRUZ

Trả lời

10

Một số năm trước, tôi đã gặp phải vấn đề tương tự.
Quay lại sau đó tôi đã phải hỗ trợ Oracle 9 và 10 nên mã chỉ chăm sóc các phiên bản đó, nhưng có lẽ nó giúp bạn tiết kiệm từ một số nghiên cứu. Ý tưởng là:

  • tìm kiếm trên registry để xác định phiên bản oracle client
  • cố gắng để tìm ra ORACLE_HOME
  • cuối cùng nhận được TNSNAMES từ CHỦ

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 trông giống như một nơi hợp lý để bắt đầu. Tất nhiên, phục vụ cho việc cài đặt không chuẩn và các tùy chọn phân giải khác nhau cũng như những thứ như Instant Client có thể sẽ cung cấp cho bạn những sợi lông màu xám. –

+0

Bạn nên thử và sử dụng các biến môi trường trước khi đăng ký trong GetOracleHome(). –

+0

Rất may là tôi không còn phải bắt kịp với Oracle nữa vì người khác đang duy trì mã này ngay bây giờ :) Nhưng kiểm tra môi trường trước khi truy vấn đăng ký có vẻ tốt. –

0

Theo mạng phụ thuộc vào phiên bản Oracle và thư mục làm việc của quy trình SQL * Plus. This first link cho bạn biết biến môi trường xác định đường dẫn cơ sở cho một số phiên bản (7, 8, 9i) của Oracle. Nếu bạn sử dụng một cái khác, tôi chắc chắn có một cách tương tự để đến thư mục hệ thống.

Nếu bạn phát tán phiên bản của các tệp này ở khắp nơi và dựa vào hành vi "tìm kiếm một tnsnames.ora đầu tiên của địa phương" của khách hàng, thì tôi đoán bạn sẽ không may mắn.

+0

Liên kết đó hơi lỗi thời, nhưng hành vi này gần giống với cách thức lên phiên bản mới nhất (11g). –

7

Trên Windows, các vị trí có nhiều khả năng nhất là %ORACLE_HOME%/network/admin hoặc %TNS_ADMIN% (hoặc cài đặt đăng ký TNS_ADMIN). Hai phần này bao gồm hầu hết mọi cài đặt.

Tất nhiên, có thể có một máy khách Oracle đang hoạt động mà không có tệp này. Oracle có một loạt các tùy chọn kết nối mạng, và có rất nhiều cách để đạt được một thiết lập làm việc với việc sử dụng TNSNAMES. Tùy thuộc vào những gì bạn đang cố gắng đạt được ở đây, cổng đầu tiên của bạn có thể là tập tin sqlnet.ora, cũng được tìm thấy trong %ORACLE_HOME%/network/admin. Điều này sẽ chứa một dòng mà trông giống như sau:

NAMES.DIRECTORY_PATH= (LDAP, TNSNAMES, HOSTNAME) 

TNSNAMES có nghĩa là nó sẽ sử dụng các tập tin TNSNAMES.ora (thứ hai trong trường hợp này). LDAPHOSTNAME là các cách thay thế để giải quyết cơ sở dữ liệu. Nếu không có TNSNAMES, tệp TNSNAMES.ora sẽ bị bỏ qua nếu nó tồn tại ở đúng nơi.

Trong C#/NET này sẽ giúp bạn có các biến môi trường:

Environment.GetEnvironmentVariable("ORACLE_HOME");

Environment.GetEnvironmentVariable("TNS_ADMIN");

+0

@Colin, Thật không may những biến này không phải lúc nào cũng được thiết lập bởi oracle client. tôi đang sử dụng oracle 11g. – RRUZ

+0

Bạn có đang sử dụng Ứng dụng khách hoặc Ứng dụng khách thường xuyên không? –

+0

Tôi tin rằng Instant Client không tạo ra% ORACLE_HOME% hoặc tnsnames.ora theo mặc định –

0

Tôi không phải là C# hay một chàng trai Windows cho rằng vấn đề vì vậy hy vọng điều này giúp. Tệp tnsnames.ora phải được đặt tại:

ORACLE_HOME\network\admin 

Nếu vị trí thay thế đã được chỉ định, nó sẽ có sẵn thông qua khóa đăng ký TNS_ADMIN.

Xem điều này link để biết thêm thông tin về cách Oracle xử lý tên tns trên 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

Danh sách này liệt kê mọi * bản sao của tnsnames.ora. Nó không hiển thị cái nào đang được sử dụng. –

+1

bạn không chỉ định rằng ... – GxG

+0

Không phải câu hỏi của tôi, nhưng bạn nói đúng, nó không rõ ràng. Trong thực tế, việc xác định tnsnames.ora nào được sử dụng thường là quan trọng, nhưng tôi nghĩ câu trả lời của bạn vẫn là một đóng góp hữu ích, với báo trước tôi đã thêm vào, vì vậy tôi đã cho bạn một upvote để chống lại downvote bạn nhận được. –