ODBCCP32.dll的SQLConfigDataSource在多Windows系统64位.NET环境失效求助
问题排查与解决方案
一、先修复现有SQLConfigDataSource代码的问题
你的代码存在几个明确错误,导致函数调用失败:
- 属性字符串格式错误
DATABASE、UID、PWD需要拆分为独立属性项,不能合并在同一行,且每个属性必须以vbNullChar结尾,最后还要额外加一个空字符作为属性列表的结束标记:
Dim Attr As String Attr = "SERVER=192.168.0.107" & vbNullChar Attr = Attr & "DSN=ERP" & vbNullChar Attr = Attr & "DESCRIPTION=DSN For ERP" & vbNullChar Attr = Attr & "DATABASE=ERPDEV" & vbNullChar Attr = Attr & "UID=edp" & vbNullChar Attr = Attr & "PWD=edp" & vbNullChar Attr = Attr & "TRUSTED_CONNECTION=no" & vbNullChar Attr = Attr & vbNullChar ' 必须添加的结束标记
- 操作类型参数混淆
SQLConfigDataSource的第二个参数uOperation对应不同操作类型,别混用:
- 创建用户DSN:
1(SQL_ADD_DSN)或4(SQL_CONFIG_DSN) - 创建系统DSN:
2(SQL_ADD_SYSTEM_DSN)或6(SQL_CONFIG_SYSTEM_DSN) - 删除用户DSN:
3(SQL_REMOVE_DSN) - 删除系统DSN:
5(SQL_REMOVE_SYSTEM_DSN)
- 32/64位程序与DLL匹配问题
- 32位VB.NET程序必须调用
C:\Windows\SysWOW64\ODBCCP32.dll - 64位程序调用
C:\Windows\System32\ODBCCP32.dll
确保DllImport声明正确:
<DllImport("ODBCCP32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)> Private Shared Function SQLConfigDataSource( _ ByVal hwndParent As IntPtr, _ ByVal uOperation As Integer, _ ByVal lpszDriver As String, _ ByVal lpszAttributes As String _ ) As Boolean End Function
- 权限问题
创建系统DSN需要管理员权限,右键程序选择「以管理员身份运行」测试,或在项目属性中设置「要求管理员」权限。
二、跨系统通用的ODBC DSN创建替代方案
方案1:使用PowerShell命令
通过调用PowerShell自动适配32/64位系统,无需依赖ODBCCP32.dll:
创建用户DSN(32位)
Start-Process "$env:windir\SysWOW64\WindowsPowerShell\v1.0\powershell.exe" -ArgumentList "Add-OdbcDsn -Name 'ERP' -DriverName 'SQL Server' -DsnType User -SetPropertyValue @('SERVER=192.168.0.107', 'DATABASE=ERPDEV', 'UID=edp', 'PWD=edp')" -Wait -NoNewWindow
创建系统DSN(64位)
Start-Process "powershell.exe" -ArgumentList "Add-OdbcDsn -Name 'ERP' -DriverName 'SQL Server' -DsnType System -SetPropertyValue @('SERVER=192.168.0.107', 'DATABASE=ERPDEV', 'UID=edp', 'PWD=edp')" -Wait -NoNewWindow -Verb RunAs
删除DSN
# 删除用户DSN Remove-OdbcDsn -Name 'ERP' -DsnType User # 删除系统DSN Remove-OdbcDsn -Name 'ERP' -DsnType System
VB.NET中调用示例:
Dim psi As New ProcessStartInfo() psi.FileName = "powershell.exe" psi.Arguments = "Add-OdbcDsn -Name 'ERP' -DriverName 'SQL Server' -DsnType User -SetPropertyValue @('SERVER=192.168.0.107', 'DATABASE=ERPDEV', 'UID=edp', 'PWD=edp')" psi.WindowStyle = ProcessWindowStyle.Hidden Process.Start(psi).WaitForExit()
方案2:直接修改注册表
ODBC DSN配置存储在注册表中,直接操作更高效:
- 用户DSN(32位):
HKCU\Software\Wow6432Node\ODBC\ODBC.INI\ERP - 用户DSN(64位):
HKCU\Software\ODBC\ODBC.INI\ERP - 系统DSN(32位):
HKLM\Software\Wow6432Node\ODBC\ODBC.INI\ERP - 系统DSN(64位):
HKLM\Software\ODBC\ODBC.INI\ERP
VB.NET创建用户DSN示例:
Dim regKey As RegistryKey = Registry.CurrentUser.OpenSubKey("Software\ODBC\ODBC.INI", True) ' 创建DSN项 Dim dsnKey As RegistryKey = regKey.CreateSubKey("ERP") dsnKey.SetValue("Driver", "C:\Windows\System32\SQLSRV32.dll") ' 32位驱动用SysWOW64路径 dsnKey.SetValue("Server", "192.168.0.107") dsnKey.SetValue("Database", "ERPDEV") dsnKey.SetValue("UID", "edp") dsnKey.SetValue("PWD", "edp") dsnKey.SetValue("Description", "DSN For ERP") dsnKey.Close() ' 更新ODBC数据源列表 Dim sourcesKey As RegistryKey = regKey.OpenSubKey("ODBC Data Sources", True) sourcesKey.SetValue("ERP", "SQL Server") sourcesKey.Close() regKey.Close()
删除DSN只需删除对应注册表项即可。
内容的提问来源于stack exchange,提问作者FIPL Developer
相关产品推荐
相关产品推荐

