如何在 C# 中使用 SQLInstallDriverEx?

How to use SQLInstallDriverEx in C#?

如何重写以下函数以便在 C# 中使用它?该函数是 odbccp32.dll 的一部分,用于安装 ODBC driver.

BOOL SQLInstallDriverEx(  
     LPCSTR    lpszDriver,  
     LPCSTR    lpszPathIn,  
     LPSTR     lpszPathOut,  
     WORD      cbPathOutMax,  
     WORD *    pcbPathOut,  
     WORD      fRequest,  
     LPDWORD   lpdwUsageCount);

SQLInstallDriverEx Reference

这是我的尝试:

 [DllImport("odbccp32")]
 private static extern bool SQLInstallDriverEx(
      string lpszDriver,
      string lpszPathIn,
      out string lpszPathOut,
      ushort cbPathOutMax,
      out uint pcbPathOut,
      ushort fRequest,
      out uint lpdwUsageCount);

我们也将不胜感激。

p/Invoke 工具包生成以下内容:

[DllImport("odbccp32.dll")]
public static extern  bool SQLInstallDriverEx(
     [In, MarshalAs(UnmanagedType.LPStr)] string lpszDriver, 
     [In, MarshalAs(UnmanagedType.LPStr)] string lpszPathIn,
     [MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder lpszPathOut, 
     ushort cbPathOutMax, ref ushort pcbPathOut, ushort fRequest, ref uint lpdwUsageCount);

public const ushort ODBC_INSTALL_INQUIRY = 1;
public const ushort ODBC_INSTALL_COMPLETE = 2;

In/MarshalAs 属性可能不是必需的。 StringBuilders 适用于 "out" 字符串,因为编组器知道如何在后台进行转换。您需要调用该方法两次,一次是解析 path/path 长度,第二次是传递这些值。如果您事先知道这些,则可以跳过该步骤,但路径 can 如果驱动程序已经存在或路径太长,请更改您提供的内容。第二次调用要求 lpszPathOut 为非空且 cbPathOutMax 为非零。

您传递给该方法的驱动程序描述由一个空字节终止字符串列表组成。该列表以双空终止。

// if target path is null, it should default to the system directory
var targetPath = @"c:\windows\system32";
ushort len = 0; uint usageCount=0;

// replace this with your actual driver description, note the double [=11=] at the end
var driver = "Text[=11=]Driver=TEXT.DLL[=11=]Setup=TXTSETUP.DLL[=11=]FileUsage=1[=11=]"
           + "FileExtns=*.txt,*.csv[=11=][=11=]";

var ret = SQLInstallDriverEx(driver, targetPath, null, 0, 
                 ref len, ODBC_INSTALL_INQUIRY, ref usageCount);
if (ret) {
    var sbPath = new StringBuilder(len);
    if (ret = SQLInstallDriverEx(driver, targetPath, sbPath, len, 
                 ref len, ODBC_INSTALL_COMPLETE, ref usageCount)) {

        // sbPath will now contain the actual path, which may be different 
        // if there is a previous installation or the path was truncated
        // perhaps check here if that was intended

        // usageCount will be updated by the system
   }
}

if (!ret) {
    // query SqlInstallerError(...) here
}

如果 return 值为 false,您将需要调用您还必须导入的 SqlInstallerError 方法。幸运的是,此方法有一个 p/invoke 页面以及如何调用它,请访问 http://www.pinvoke.net/default.aspx/odbccp32/SQLInstallerError.html。错误代码及其含义已在您链接的 MSDN 页面上进行了概述。

请注意,您可以跳过两阶段方法调用并使用 ODBC_INSTALL_COMPLETE 调用一次,前提是您提供了正确的 buffer/sizes.