IBM DB2问题--System.BadImageFormatException: 无法加载文件或程序集IBM.DB2.DLL或其某个依赖项。

4

我收到了上述提到的错误信息。我已经进行了足够的研究并尝试了各种选项,但仍然没有运气。

以下是详细信息:

OS: Windows 7 64 bit version

    Visual studio version: 2013 Premium

   .NET framework version is : 4.0.30319

   ASP.NET version: 4.0.30319.34249

   IIS version: 7.0

   DB2 installed path: C:\Program Files (x86)\IBM

   DLL path: C:\Program Files (x86)\IBM\SQLLIB\BIN\netf40\IBM.DB2.dll

   DLL Version: 9.7.4.4

我还将我的解决方案配置管理器平台更改为Any CPU,并将应用程序池中的设置更改为将属性启用 32 位应用程序设置为 True
但是我仍然遇到相同的错误。是否有其他方法解决?
请给我您的建议。
7个回答

4
这个问题最近困扰了我,按照这份IBM文档的说法解决了。即在项目引用中将DB2 dlls的“复制本地”设置为false,直接引用来自DB2客户端安装的dlls。

3

我要介入并分享我的步骤,以完全自动化部署IBM的.Net数据提供程序,因为这是我尝试让它正常工作时遇到的第一个错误,也是众多错误中的第一个。我希望通过阅读这些步骤,有人可以避免被困在痛苦之轮上。

  1. Add the reference to the DB2 .Net Data Providers using nuget: https://www.nuget.org/packages/IBM.Data.DB2/ You will notice that it give you a hint of the pain you are about to endure: NOTICE - This packakge requires the IBM DB2 client software to be installed locally and available on your %PATH% environment variable.
  2. Next, you will need to set the DLLs that you just referenced not be included in the BIN folder by setting the DLLs to Copy Local FALSE by Right Clicking the references and going to properties.

    If these are put in the BIN you will get the error message:

    [BadImageFormatException: Could not load file or assembly 'IBM.Data.DB2' or one of its dependencies. An attempt was made to load a program with an incorrect format.]

    IBM's reference to the issue: http://www-01.ibm.com/support/docview.wss?uid=swg21902663

  3. Now in order to begin developing you will need to install the driver packages or the run time client from here https://www-945.ibm.com/support/fixcentral/ (good luck) or you will be receiving the following errors:

    Exception Message: Could not load file or assembly 'IBM.Data.DB2, Version=9.7.4.4, Culture=neutral, PublicKeyToken=7c307b91aa13d208' or one of its dependencies. The system cannot find the file specified.

  4. Developing time! Have fun!
  5. Now you need to deploy and you realize you have a problem with automating installing a DB2 driver and start looking for solutions:

    How to properly deploy IBM DB2 data provider

    ASP.NET -- IIS7 -- IBM DB2 Issue

    Not wanting to manually install on DEV/QA/STG/PROD, I found the that you can install IBM Data Server Client Package silently via command line using a response file. About halfway down this page: https://www.ibm.com/support/knowledgecenter/SSEPGG_11.1.0/com.ibm.swg.im.dbclient.install.doc/doc/t0007315.html you will find the relevant information after this line:

    To install the IBM Data Server Driver Package software, run the v10.5fpX_ntxYY_dsdriver_EN command. The X represents the fix pack number value and the YY represents either 32-bit or 64-bit release.

    A link to a sample response file to copy and change with your information is here: https://www.ibm.com/support/knowledgecenter/SSEPGG_11.1.0/com.ibm.db2.luw.apdv.sample.doc/doc/dsdriver/s-dsdriver-rsp.html

  6. Now you are all set right? WRONG. Apparently a "successful install" doesn't include moving the appropriate DLLs to the GAC and registering them in the Registry. Thanks IBM: https://www-01.ibm.com/support/docview.wss?uid=swg21618434

    Not wanting to give up in my automated deploy dreams, I put all the above knowledge into a Powershell script:

    param([string]$driverPath,[string]$installPath)    
    
    [System.Reflection.Assembly]::Load("System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")            
    $publish = New-Object System.EnterpriseServices.Internal.Publish    
    
    Write-output "Installing v11.1.2fp2a_ntx64_dsdriver_EN.exe"
    & "$driverPath\v11.1.2fp2a_ntx64_dsdriver_EN.exe" /u "$driverPath\DB2.cfg" /l "$driverPath\log.txt" | Out-null
    
    $publish.GacInstall("$installPath\bin\netf20\IBM.Data.DB2.dll") | Out-null
    $publish.GacInstall("$installPath\bin\netf20_32\IBM.Data.DB2.dll") | Out-null
    $publish.GacInstall("$installPath\bin\netf40\IBM.Data.DB2.dll") | Out-null
    $publish.GacInstall("$installPath\bin\netf40_32\IBM.Data.DB2.dll") | Out-null
    $publish.GacInstall("$installPath\bin\netf20\IBM.Data.DB2.Entity.dll") | Out-null
    $publish.GacInstall("$installPath\bin\netf20_32\IBM.Data.DB2.Entity.dll") | Out-null
    $publish.GacInstall("$installPath\bin\netf40\IBM.Data.DB2.Entity.dll") | Out-null
    $publish.GacInstall("$installPath\bin\netf40_32\IBM.Data.DB2.Entity.dll") | Out-null
    
  7. Now you will find that you are getting another error. Until now you were only fighting IBM.Data.DB2.*.dll issues. The following error is now present:

    Exception Message: Unable to load DLL 'db2app64.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)

    Come on IBM!! A quick Google search finds the same results we got with the #1. "Change your app to 32-bit" This is wrong, of course, we know better now!

    I'll help you out and let you know that this DLL was installed along with the OTHER DLLs, just in a different path!

    Just add them to the bottom of the Powershell script:

    $publish.GacInstall("$installPath\bin\db2app.dll") | Out-null
    $publish.GacInstall("$installPath\bin\db2app64.dll") | Out-null
    
现在您可以使用完全自动化的DB2 .Net提供程序连接到DB2服务器。
希望这可以帮助您。
编辑:您也可以将所需的DLL文件隔离出来,仅将它们包含在一个文件夹(如/lib/)中并部署这些文件,而不是使用exe安装。引用/lib/位置而不是驱动程序安装位置以移动到GAC。

虽然你的帖子有些年代了,但对我非常有帮助。这是我的经验总结:
  1. 如果没有nuget包,请安装客户端SDK,并确保正确选择环境(32/64位)。
  2. 将项目包含在vs中时,请将“复制本地”设置为false。
  3. 服务器安装(使用正确的环境32/64位主机应用程序)-不包括informix驱动程序,只有db2。运行informix的客户端sdk安装程序。
  4. 出现异常缺少其他dll文件。更新路径变量以指向install/bin目录。重新启动服务器使路径生效。无需手动在GAC中注册其他dll文件。
- Jim
感谢您提供的出色答案。帮助我安装了这个“野兽”。需要注意的是:确保安装您拥有许可证的Nuget包和客户端运行时版本(不一定是最新版本)。当然,还要安装*.cer文件(并非所有安装都需要)和*.lic许可证。有关许可证安装的更多信息,请参见此处:https://www.ibm.com/support/producthub/db2/docs/content/SSEPGG_11.5.0/com.ibm.db2.luw.qb.server.doc/doc/t0023608.html 您将使用客户端运行时来安装许可证。 - Alex

2
在我的情况下,这是发生在Windows Server 2012 R2标准版上的问题。这是由于包没有安装在全局缓存程序集中所导致的错误,请确保您检查C:\Windows\Assembly以确保您的程序已正确安装在GAC_32、GAC_64下,您应该会看到...

enter image description here

如果不是这样,我就必须这样做才能解决它。
1)我必须检查已安装的版本以确保兼容性。
2)由于一个错误,"IBM数据服务器客户端"没有通过GUI正确安装,所以必须以管理员身份静默运行。
3)由于服务器的特殊性质,我必须使用IBM-Steps <-- 链接安装 .Net 3.5。但那对我不起作用,所以我必须使用MS-Steps <-- 链接并使用以下代码。
DISM /Image:C:\test\offline /Enable-Feature /FeatureName:NetFx3 /All /LimitAccess /Source:D:\sources\sxs

4) 发现问题之一是“IBM DATA SERVER CLIENT”未正确安装,可以通过检查位于C:\User_Dir\Document\DB2LOG的DB2LOG文件夹进行确认。
5) 我必须安装“IBM DATA RUN TIME CLIENT”的最新修复程序,在我的情况下是9.7版本的修复程序10,在IBM的下载页面上可以免费获取,只需注册即可,注册只需1分钟,您会立即收到回复,请确保跟进,否则等待直到您的愚蠢因素发挥作用.........
6) 然后我就能安装“IBM DATA SERVER CLIENT”了。
7) 仔细检查以确保您可以看到“DB2COPY1”或您选择称为安装副本的任何内容。

enter image description here

我确定你不需要两个,然而我将不再去碰这个东西。

结果发现这也发生在Windows 8上,安装程序在新的磁贴界面上有问题。很奇怪,只需运行late 9.7fp10 x64,就应该可以解决问题。 - Deciantis

1

安装DB2

  • 从此链接(https://www-01.ibm.com/support/docview.wss?uid=swg27016878)下载最新的IBM数据服务器驱动程序包
  • 以管理员身份执行文件,并保留默认设置,除了它要求在本地驱动程序上安装功能的位置。单击该位置并选择在本地驱动器上安装所有功能和子功能...。不确定是否会影响。
  • 驱动程序将默认安装在C:\Program Files\IBM\IBM DATA SERVER DRIVER中。
  • 实例将默认安装在C:\ProgramData\IBM\DB2\IBMDBCL1中。此项的默认实例名称为IBMDBCL1
  • 您应该在此位置C:\ProgramData\IBM\DB2\IBMDBCL1\cfg中设置连接字符串,在此文件db2dsdriver.cfg中。
 <dsncollection>       
  <dsn alias="DBDSNSAMPLE" name="DBDSNSAMPLE" host="127.0.0.1" port="50001"/>          
 </dsncollection>     
 <databases>       
  <database name="DBDSNSAMPLE" host="127.0.0.1" port="50001">                
  </database>          
 </databases> 
</configuration>
  • 注意: 您可以从程序和功能中卸载驱动程序。
  • 添加连接后,您可以使用testconn40.exe测试连接。打开cmd并定位到C:\Program Files\IBM\IBM DATA SERVER DRIVER\bin并执行:

    > testconn40 DBDSNSAMPLE

  • 此命令不会登录您(因为我们在.cfg文件中没有指定用户凭据),但至少它将显示正确的消息,这意味着您的.NET应用程序将正常工作。否则,它将显示一些异常错误。

Visual Studio中的DB2

  • 从nuget安装IBM.Data.DB2包。
  • 然后,在引用中,您将看到IBM.Data.DB2.dllIBM.Data.DB2.Entity.dll两者。
  • 以下是测试代码:
   using (var conn = new DB2Connection($"Database={u.db2a};UserID={u.db2u};Password={u.db2p};Server={u.db2i}"))
   using (var cmd = new DB2Command())
   {

       cmd.CommandText = "SELECT * FROM Table1";
       cmd.Connection = conn;
       conn.Open();
       using (var reader = cmd.ExecuteReader())
       {
           while (reader.Read())
           {

               Console.WriteLine(reader.GetValue(3));
           }
       }
   }

注意事项

  • 如果dll出现问题: 进入引用并单击IBM.Data.DB2,在属性窗口中将复制本地设置为False。对IBM.Data.DB2.Entity同样如此。(这将确保这两个dll不会在构建/编译项目时出现在bin文件夹中。相反,项目将从GAC中使用这些DLLS。我们只是使用它们来解决我们的代码)
  • 另一件事是,可能是那些dll在初始安装时没有正确安装到GAC中。因此,您可以尝试手动安装它们: 进入Visual Studio的开发人员命令提示符,逐步运行这些行:
gacutil /i "C:\Program Files\IBM\IBM DATA SERVER DRIVER\bin\netf20\IBM.Data.DB2.dll"
gacutil /i "C:\Program Files\IBM\IBM DATA SERVER DRIVER\bin\netf20_32\IBM.Data.DB2.dll"
gacutil /i "C:\Program Files\IBM\IBM DATA SERVER DRIVER\bin\netf40\IBM.Data.DB2.dll"
gacutil /i "C:\Program Files\IBM\IBM DATA SERVER DRIVER\bin\netf40_32\IBM.Data.DB2.dll"
gacutil /i "C:\Program Files\IBM\IBM DATA SERVER DRIVER\bin\netf20\IBM.Data.Informix.dll"
gacutil /i "C:\Program Files\IBM\IBM DATA SERVER DRIVER\bin\netf20_32\IBM.Data.Informix.dll"
gacutil /i "C:\Program Files\IBM\IBM DATA SERVER DRIVER\bin\netf40\IBM.Data.Informix.dll"
gacutil /i "C:\Program Files\IBM\IBM DATA SERVER DRIVER\bin\netf40_32\IBM.Data.Informix.dll"
gacutil /i "C:\Program Files\IBM\IBM DATA SERVER DRIVER\bin\netf20\IBM.Data.DB2.Entity.dll"
gacutil /i "C:\Program Files\IBM\IBM DATA SERVER DRIVER\bin\netf20_32\IBM.Data.DB2.Entity.dll"
gacutil /i "C:\Program Files\IBM\IBM DATA SERVER DRIVER\bin\netf40\IBM.Data.DB2.Entity.dll"
gacutil /i "C:\Program Files\IBM\IBM DATA SERVER DRIVER\bin\netf40_32\IBM.Data.DB2.Entity.dll"
gacutil /i "C:\Program Files\IBM\IBM DATA SERVER DRIVER\bin\db2app.dll"
gacutil /i "C:\Program Files\IBM\IBM DATA SERVER DRIVER\bin\db2app64.dll"

你可以在命令提示符中尝试以下操作:

regsvr32 "C:\Program Files\IBM\IBM DATA SERVER DRIVER\bin\db2app64.dll"
regsvr32 "C:\Program Files\IBM\IBM DATA SERVER DRIVER\bin\db2app.dll"

此外,在执行这些操作之前,您需要确保您与供应商之间的连接是开放的(无论是VPN、站点到站点VPN等)。

0

我曾经遇到过同样的问题,并从以下链接中找到了解决方案。当我删除本地副本并将复制到本地属性设置为False时,它起作用了。

解决方案链接


0

看起来你正在尝试从一个在64位模式下运行的.NET应用程序中加载一个32位编译的IBM DB2驱动程序。尝试将配置管理器更改为以x86模式运行。


他明确表示该应用程序是AnyCPU,应用程序池允许32位。 - thomasb
我的解决方案设置为任意CPU,因此它应该在x86和x64上都可以运行,对吗? - Sam
任何 CPU 意味着它将根据多种因素运行在 x86 或 x64 上;操作系统、IIS 模式等。我建议尝试在显式的 x86 模式下编译,以防万一启用 32 位应用程序出现了某些未知的问题。 - KrisG
@KrisG 尝试使用 x86,但没有运气。 - Sam

0

我最近遇到了这个问题。我发现在Visual Studio的发布过程中,会将IBM.Data.DB2.dll的一个副本放在Web应用程序的BIN目录中。当手动删除它时,Web应用程序开始正常运行。我不知道为什么它会被发布,因为它没有直接引用。

我发现解决这个问题最简单的方法是使用后期构建事件。

项目属性-->生成事件-->后期构建事件命令行

这是我正在使用的命令行:

del $(TargetDir)\IBM.Data.DB2.dll

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接