2008-12-02 9 views
27

मैं एक विरासत अनुप्रयोग पर काम कर रहा हूं जिसमें सी ++ विस्तारित संग्रहीत प्रक्रिया है। यह xsproc डेटाबेस से कनेक्ट करने के लिए ओडीबीसी का उपयोग करता है, जिसका अर्थ है कि इसे एक डीएसएन कॉन्फ़िगर करने की आवश्यकता है।मैं सी # का उपयोग कर ओडीबीसी डीएसएन प्रविष्टि कैसे बना सकता हूं?

मैं इंस्टॉलर अपडेट कर रहा हूं (विजुअल स्टूडियो 2008 सेटअप प्रोजेक्ट का उपयोग करके बनाया गया है), और एक कस्टम एक्शन होना चाहता हूं जो ओडीबीसी डीएसएन प्रविष्टि बना सकता है, लेकिन Google पर उपयोगी जानकारी खोजने के लिए संघर्ष कर रहा हूं।

क्या कोई मदद कर सकता है?

उत्तर

31

मैंने वास्तव में रजिस्ट्री में हेरफेर करके इसे अंत में हल किया। मैं एक वर्ग बना लिया है कार्यक्षमता, सामग्री जिसमें से मैं यहाँ शामिल किया है को रोकने के लिए:

///<summary> 
/// Class to assist with creation and removal of ODBC DSN entries 
///</summary> 
public static class ODBCManager 
{ 
    private const string ODBC_INI_REG_PATH = "SOFTWARE\\ODBC\\ODBC.INI\\"; 
    private const string ODBCINST_INI_REG_PATH = "SOFTWARE\\ODBC\\ODBCINST.INI\\"; 

    /// <summary> 
    /// Creates a new DSN entry with the specified values. If the DSN exists, the values are updated. 
    /// </summary> 
    /// <param name="dsnName">Name of the DSN for use by client applications</param> 
    /// <param name="description">Description of the DSN that appears in the ODBC control panel applet</param> 
    /// <param name="server">Network name or IP address of database server</param> 
    /// <param name="driverName">Name of the driver to use</param> 
    /// <param name="trustedConnection">True to use NT authentication, false to require applications to supply username/password in the connection string</param> 
    /// <param name="database">Name of the datbase to connect to</param> 
    public static void CreateDSN(string dsnName, string description, string server, string driverName, bool trustedConnection, string database) 
    { 
     // Lookup driver path from driver name 
     var driverKey = Registry.LocalMachine.CreateSubKey(ODBCINST_INI_REG_PATH + driverName); 
     if (driverKey == null) throw new Exception(string.Format("ODBC Registry key for driver '{0}' does not exist", driverName)); 
     string driverPath = driverKey.GetValue("Driver").ToString(); 

     // Add value to odbc data sources 
     var datasourcesKey = Registry.LocalMachine.CreateSubKey(ODBC_INI_REG_PATH + "ODBC Data Sources"); 
     if (datasourcesKey == null) throw new Exception("ODBC Registry key for datasources does not exist"); 
     datasourcesKey.SetValue(dsnName, driverName); 

     // Create new key in odbc.ini with dsn name and add values 
     var dsnKey = Registry.LocalMachine.CreateSubKey(ODBC_INI_REG_PATH + dsnName); 
     if (dsnKey == null) throw new Exception("ODBC Registry key for DSN was not created"); 
     dsnKey.SetValue("Database", database); 
     dsnKey.SetValue("Description", description); 
     dsnKey.SetValue("Driver", driverPath); 
     dsnKey.SetValue("LastUser", Environment.UserName); 
     dsnKey.SetValue("Server", server); 
     dsnKey.SetValue("Database", database); 
     dsnKey.SetValue("Trusted_Connection", trustedConnection ? "Yes" : "No"); 
    } 

    /// <summary> 
    /// Removes a DSN entry 
    /// </summary> 
    /// <param name="dsnName">Name of the DSN to remove.</param> 
    public static void RemoveDSN(string dsnName) 
    { 
     // Remove DSN key 
     Registry.LocalMachine.DeleteSubKeyTree(ODBC_INI_REG_PATH + dsnName); 

     // Remove DSN name from values list in ODBC Data Sources key 
     var datasourcesKey = Registry.LocalMachine.CreateSubKey(ODBC_INI_REG_PATH + "ODBC Data Sources"); 
     if (datasourcesKey == null) throw new Exception("ODBC Registry key for datasources does not exist"); 
     datasourcesKey.DeleteValue(dsnName); 
    } 

    ///<summary> 
    /// Checks the registry to see if a DSN exists with the specified name 
    ///</summary> 
    ///<param name="dsnName"></param> 
    ///<returns></returns> 
    public static bool DSNExists(string dsnName) 
    { 
     var driversKey = Registry.LocalMachine.CreateSubKey(ODBCINST_INI_REG_PATH + "ODBC Drivers"); 
     if (driversKey == null) throw new Exception("ODBC Registry key for drivers does not exist"); 

     return driversKey.GetValue(dsnName) != null; 
    } 

    ///<summary> 
    /// Returns an array of driver names installed on the system 
    ///</summary> 
    ///<returns></returns> 
    public static string[] GetInstalledDrivers() 
    { 
     var driversKey = Registry.LocalMachine.CreateSubKey(ODBCINST_INI_REG_PATH + "ODBC Drivers"); 
     if (driversKey == null) throw new Exception("ODBC Registry key for drivers does not exist"); 

     var driverNames = driversKey.GetValueNames(); 

     var ret = new List<string>(); 

     foreach (var driverName in driverNames) 
     { 
      if (driverName != "(Default)") 
      { 
       ret.Add(driverName); 
      } 
     } 

     return ret.ToArray(); 
    } 
} 
+1

मेरे लिए काम किया, सिर्फ एक बदला "सर्वर" से "Servername" में प्रविष्टि। शायद यह विंडोज 7 में एक बदलाव है। – newenglander

2

CodeProject page on reading ODBC information है।

पढ़ना आपको उस जानकारी को अवश्य देना चाहिए जो आपको आवश्यक रजिस्ट्री प्रविष्टियों को लिखने वाले इंजीनियर को रिवर्स करने के लिए आवश्यक है।

उस कोड से;

private const string ODBC_LOC_IN_REGISTRY = "SOFTWARE\\ODBC\\"; 
    private const string ODBC_INI_LOC_IN_REGISTRY = 
      ODBC_LOC_IN_REGISTRY + "ODBC.INI\\"; 

    private const string DSN_LOC_IN_REGISTRY = 
      ODBC_INI_LOC_IN_REGISTRY + "ODBC Data Sources\\"; 

    private const string ODBCINST_INI_LOC_IN_REGISTRY = 
      ODBC_LOC_IN_REGISTRY + "ODBCINST.INI\\"; 

    private const string ODBC_DRIVERS_LOC_IN_REGISTRY = 
      ODBCINST_INI_LOC_IN_REGISTRY + "ODBC Drivers\\"; 
0

इस कोड को उपलब्ध कराने के लिए धन्यवाद, मैं इसे अपने आप का इस्तेमाल किया है।

driverName प्राप्त करने के लिए मैं CreateSubKey के बजाय OpenSubKey उपयोग करने के लिए मूल्यों को प्राप्त करने के लिए किया था: मैं दो चीजें मुश्किल बदलना पड़ा जब से मैं Vista चला रहा हूँ

// Lookup driver path from driver name 
var driverKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(
     ODBCINST_INI_REG_PATH + driverName); 

, मैं एक आवेदन प्रकट का इस्तेमाल किया था और सेट requestedPrivileges रहे हैं:

<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/> 

निम्न आलेख मुझे मदद की OpenSubKey मुद्दा लगता है: http://www.daveoncsharp.com/2009/08/read-write-delete-from-windows-registry-with-csharp/

बार्नवेल के कोड के लिए 210
2

+1!

हालांकि, मैं सोचता हूं उनके DSNExists() गलत कुंजी से पूछताछ कर रहे हैं। मुझे लगता है कि यह इस होना चाहिए:

public static bool DSNExists(string dsnName) 
{ 
    var sourcesKey = Registry.LocalMachine.CreateSubKey(ODBC_INI_REG_PATH + "ODBC Data Sources"); 
    if (sourcesKey == null) throw new Exception("ODBC Registry key for sources does not exist"); 

    return sourcesKey.GetValue(dsnName) != null; 
} 
+0

यह सच है! और देखने के लिए दूसरी चीज वर्चुअलाइजेशन है। 64 बिट ओएस पर कुंजी "सॉफ़्टवेयर \ वाह 6432 नोड \ ओडीबीसी \ ओडीबीसी.आईएनआई \ ओडीबीसी डेटा स्रोत" – gsubiran

7

इस तरह काम करना के लिए एक API नहीं है। एपीआई का उपयोग करने से यह भी सुनिश्चित होगा कि आपका एप्लिकेशन विंडोज के नए संस्करणों के साथ संगत रहेगा। एपीआई यहां पाया जा सकता:

http://msdn.microsoft.com/en-us/library/ms716476(VS.85).aspx

सी # में इस समारोह PInvoking PInvoke.net पर पाया जा सकता।

0

धन्यवाद यह अगर आप कर रहे हैं एक dsn शायद उत्कृष्टता इस

var dsnKeyEng = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(ODBC_INI_REG_PATH + dsnName + "\\Engines"); 
var dsnKeyExl = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(ODBC_INI_REG_PATH + dsnName + "\\Engines\\Excel"); 

dsnKeyExl.SetValue("FirstRowHasNames", 01); 
dsnKeyExl.SetValue("MaxScanRows", 8); 
dsnKeyExl.SetValue("Threads",3); 
dsnKeyExl.SetValue("UserCommitSync", "Yes") 
8
इसके अलावा chrfalch's post को

की तरह कुछ जोड़ने की जरूरत के लिए एक बहुत मदद किया गया था, यहाँ एक DSN अद्यतन करने के लिए कुछ नमूना कोड है (मैं जानता हूँ कि ओ पी है निर्माण के लिए पूछ रहा है, लेकिन इस कोड जो कुछ भी आप सब करने की ज़रूरत) API कॉल का उपयोग करने के बजाय सीधा रजिस्ट्री के माध्यम से (pinvoke.net page से जानकारी का उपयोग कर आसानी से अनुवाद है): -

[DllImport("ODBCCP32.DLL", CharSet = CharSet.Unicode, SetLastError = true)] 
static extern bool SQLConfigDataSourceW(UInt32 hwndParent, RequestFlags fRequest, string lpszDriver, string lpszAttributes); 

enum RequestFlags : int 
{ 
    ODBC_ADD_DSN = 1, 
    ODBC_CONFIG_DSN = 2, 
    ODBC_REMOVE_DSN = 3, 
    ODBC_ADD_SYS_DSN = 4, 
    ODBC_CONFIG_SYS_DSN = 5, 
    ODBC_REMOVE_SYS_DSN = 6, 
    ODBC_REMOVE_DEFAULT_DSN = 7 
} 

bool UpdateDsnServer(string name, string server) 
{ 
    var flag = RequestFlags.ODBC_CONFIG_SYS_DSN; 
    string dsnNameLine = "DSN=" + name; 
    string serverLine = "Server=" + server; 

    string configString = new[] { dsnNameLine, serverLine }.Aggregate("", (str, line) => str + line + "\0"); 

    return SQLConfigDataSourceW(0, flag, "SQL Server", configString); 
} 
+0

हो सकता है मैं रजिस्ट्री के साथ मैकिंग पर एपीआई दृष्टिकोण पसंद करता हूं, और अधिक एपीआई यहां http://support.microsoft.com/kb/142,216 – PeskyGnat

संबंधित मुद्दे