compiled exe is missing zlib1.dll
Ogglord
Posts: 2
Hi, I'm evaluating Packager. When I've created the exe from my project and started SQLPackage.exe, and then press Run I'm greeted by
Unable to load DLL 'zlib1.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
There is no file with that name, it's the compression library, isn't it?
/ Oscar
Unable to load DLL 'zlib1.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
There is no file with that name, it's the compression library, isn't it?
/ Oscar
Comments
Yes, it is. When you create a SQL Package using compression, the zlib1.dll is copied to a folder in your %TMP% directory and referenced from your package to decompress the SQL code inside.
I suppose the first things to check are that you are running the latest version of SQL Packager to create the package and that you have read/write access to the folder pointed at by the TMP environment variable.
Steven
Here is another idea: I think the user running the package needs read/write permissions to the folder that the package is being run from.
Any other ideas?
Many thanks
Steven Elliott
Please check to see if zlib1.dll is getting extracted from your package when you run it. There should be a subfolder in your %tmp% folder (normally this is in c:\documents and settings\you\temp) with a format similar to tmp86.tmp15303109. Zlib1.dll should be in there. In order to find this temporary folder more easily, you can tell explorer to 'view details' and sort on last modified date.
If the file does not appear, you may not have read/write access to the temporary folder.
Another thing that's happened in the past is that some anti-virus software has flagged the creation of assemblies in the temporary folder as 'suspicious'. You may want to try temporarily disabling any antivirus applications and see if that helps.
c:\Users\Ron\AppData\Local\Temp.
The machine has no virus checker installed.
I thought I would try to work around this by putting the Zlib1.dll in the same folder as the packager exe. When I ran it I got the following error
"An attempt was amde to a load aprogram with an incorrect format". I have seen this issue where 32 bit apps/dlls try to call 64 bit dlls. Is this any help?
Many thanks
Steven Elliott
This is exactly the same idea I had, but the information you had provided indicated that all of the code was 32-bit.
What versions of .NET Framework are installed? All packages should be specifically targetted to .NET Framework 1.1. This wouldn't come with Vista -- maybe downloading the Microsoft .NET Framework 1.1 redistributable from http://www.microsoft.com/downloads and installing this may get it to work.
Steven Elliott
Steven Elliott
It works fine on Windows XP 64. I tried that yesterday.
If you create some registry entries in the HKEY_LOCAL_MACHINE\Software\Microsoft\Fusion key:
REG_DWORD LogFailures 1
REG_SZ LogPath c:\FusionLog
Create a folder called 'FusionLog' in c:This should leave a bunch of HTML files in a subfolder named after the executable name of your package. Each file will be a failed assembly binding attempt with more information about why the binding had failed.
The error log from the Fusion Log folder is as follows....
*** Assembly Binder Log Entry (05/06/2007 @ 14:13:02) ***
The operation failed.
Bind result: hr = 0x80070002. The system cannot find the file specified.
Assembly manager loaded from: C:\Windows\Microsoft.NET\Framework64\v2.0.50727\mscorwks.dll
Running under executable C:\Program Files\Shire Systems\Food Sentinel\Database Scripts\UpdateLive_0001_0000_0006_07151_0001_0000_0007_07152.exe
--- A detailed error log follows.
=== Pre-bind state information ===
LOG: User = Ron-PC\Ron
LOG: DisplayName = RedGate.Compression.ZLib, Version=5.3.0.2, Culture=neutral, PublicKeyToken=7f465a1c156d4d57
(Fully-specified)
LOG: Appbase = file:///C:/Program Files/Shire Systems/Food Sentinel/Database Scripts/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = UpdateLive_0001_0000_0006_07151_0001_0000_0007_07152.exe
Calling assembly : UpdateLive_0001_0000_0006_07151_0001_0000_0007_07152, Version=1.0.2708.16557, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v2.0.50727\config\machine.config.
LOG: Post-policy reference: RedGate.Compression.ZLib, Version=5.3.0.2, Culture=neutral, PublicKeyToken=7f465a1c156d4d57
LOG: GAC Lookup was unsuccessful.
LOG: Attempting download of new URL file:///C:/Program Files/Shire Systems/Food Sentinel/Database Scripts/RedGate.Compression.ZLib.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/Shire Systems/Food Sentinel/Database Scripts/RedGate.Compression.ZLib/RedGate.Compression.ZLib.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/Shire Systems/Food Sentinel/Database Scripts/RedGate.Compression.ZLib.EXE.
LOG: Attempting download of new URL file:///C:/Program Files/Shire Systems/Food Sentinel/Database Scripts/RedGate.Compression.ZLib/RedGate.Compression.ZLib.EXE.
LOG: All probing URLs attempted and failed.
Using CorFlags.exe from the .Net SDK (http://www.process64.com/SettingPlatformDependencyBitsInNet20.aspx), we've set the bit flags on the compiled exe to force it to always run as a 32 bit process. Our installer now works on both 32 and 64 bit hardware.
When viewing our fusion logs, we were also having the binding failure with the Zlib dll, but it still works correctly without it. The real problem was the 64 bit issue.
I've noticed this on my own 32-bit system as well. Any time you run a package it seems to fail on one binding attempt and then proceed to work regardless.
What seems to be happening is that the compression library is extracted from the resources into a temporary file in %TMP%\Red Gate, then the file is loaded into the AppDomain as an assembly. It's not clear exactly how .NET Framework is doing that, but if experience serves me right it probably puts the assembly in the %TMP%\something.tmp folder.
So maybe logging the assembly bindings isn't really the way to go, because the assembly is being loaded from disk right into the AppDomain (AppDomain.CurrentDomain.Load).
With compression enabled, the packaged database (packaged on a 32 bit machine) fails on a 64 bit machine.
With compression disabled, the packaged database (packaged on a 32 bit machine) succeeds on a 64 bit machine.
Is there an issue with the compression dll on a 64 bit machine that would cause this problem?
I'm sorry I am unable to reproduce the problem, on an x64 computer with 64-bit Windows, a package built on a 32-bit edition of Windows will run just fine.
What I'm trying to get to the bottom of is whether the standard packager output has an issue with 64 bit, or whether it is specific to the modified template solution I am using.
I've tried some tests with differing results:
Using the modified template solution as a base, I used my code to generate a C# .exe file. This will run fine on 32 or 64 bit with compression disabled, and on 64 bit with compression disabled, but crashes on 64 bit with compression enabled.
Using the modified template solution as a base (ie. replacing the one in C:\Program Files\Red Gate\SQL Bundle 5\SQL Packager Code Templates\C#), I used the Red Gate SQL Packager version 5.2.0.49 to generate a C# .exe file. This will run fine on both 32 or 64 bit with compression disabled or enabled.
It seems that something in the way the PackagerEngine.Package() method compiles the output causes this issue.
Using my 'custom' code template:
Compression disabled: works ok
Compression enabled: crashes
Using the 'factory' version of SQL Packager code template:
Compression disabled: works ok
Compression enabled: crashes
So it doesn't look like the template is the cause of the problem. I also tried making sure the RedGate.Compression.ZLib.dll was present in next to the packages with compression enabled to make sure it wasn't just a binding problem, but that made no difference.
I still think it would work if you changed the OutputType from Executable to Project, then manually compiled it with Visual Studio, after setting the platform target to x86 instead of Any CPU.
If that works, maybe we could find a way for packager to create its' executables this way.
Compiling this project using VS2003, it fails with an error to do with loading resources. (Is the option to compile for x86 available in VS2003 - I thought this was a VS2005+ option only?)
Compiling this project using VS2005 for "any CPU", it fails with the usual error.
Compiling this project using VS2005 for "x86", it works.
Could it possibly be something to do with the fact the my application is running under .Net 2.0, creating the package project as a VS2003 project, which the PackagerEngine then compiles under .Net 1.1?
Regarding the current thread, I have not modified or changed the code templates, I am using the product 'out of the box'.
Many thanks for your suggestions
Steven Elliott
I have noted this down in our internal documentation so we can use it if this issue comes up again. Thanks for letting us know what your solution was.