Mittwoch, 17. März 2010

py2exe VC-library woes (part two)

I've got a shiny new desktop pc in my office last week. First thing to setup was my development environment. So among other stuff I installed python (2.6.4), wxpython, py2exe and tested the install with one of my projects.

But generating a stand alone windows executable failed immediately:
python py2exe
...bailed out with following message:
*** searching for required modules ***
*** parsing results ***
*** finding dlls needed ***
error: MSVCP90.dll: No such file or directory

What happended?

This time I installed python with local admin rights "for all users". As noted in my first post about distributing python apps for windows python >2.6 (on the windows platform) is linked against Microsoft Visual C libraries (VC90) and the preferred way for installing those dependencies is to put them into the Windows\WinSxS system directory - where assemblies can be shared "side by side" among applications.

That's exactly what the python msi installer does when it is given the "install for all users" option with the required admin-privileges. But unfortunately current versions of py2exe don't seem to check system directories when they scan for required modules and thus fail. This seems to be confirmed as a bug.

The workarounds:

You have two obsolete and one recommended options:
  1. Locate the correct version and copy msvcp90.dll and msvcr90.dll into pythons DLLs directory
  2. Install Python without admin rights (for yourself only)
  3. [EDIT 2010-09-19] RECOMMENDED: add msvcp90.dll to dll_excludes of your py2exe options in like so:

## note the exclusion of msvcp90.dll to fix the error in py2exe
my_dll_excludes = [
    'libgdk-win32-2.0-0.dll', 'libgobject-2.0-0.dll',
    'tcl84.dll', 'tk84.dll', 'msvcp90.dll'
    options = {...
               "py2exe": {"dll_excludes": my_dll_excludes, ...
Take care to package the correct version of msvcp90.dll and msvcr90.dll with your app according to this blog.

Montag, 8. Februar 2010

Distributing python apps for the windows platform

So you've kept your python code platform independent and struggled through the process of generating windows executables via a py2exe aware script? Congratulations - you're ready to create a setup package! But if using a python version >2.6 you'll have to solve the visual C++ runtime issues! Python and your derived apps are linked against VC libraries and contain a version specification (called "assemblies") to access the correct set of DLLs. You can fetch that XML coded info from your python exe or dll files using my script and it will look like this:

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
        <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>

Howto locate required VC DLLs

  • Download into a folder of your choice.
  • Using the windows console execute (make sure to adjust the paths):
    >cd C:\path\to\getassembly
    >python C:\python26\python.exe
  • In the output you'll find the dependentAssembly that holds all information you need to find the correct folder for copying the correct set of DLLs:
        <assemblyIdentity type="win32" name="Microsoft.VC90.CRT"
        version="9.0.21022.8" processorArchitecture="x86"
  • In the example above this would be on my system:

You have two packaging options to fullfill the dependencies listed in the manifest:
  1. Install Microsoft.VC90.CRT.manifest, msvcp90.dll and msvcr90.dll as a "private assembly" into the application directory (provided that you have the license to distribute those files).
  2. Preferred: Include the redistributable installer vcredist_x86.exe. It will setup a shared "side by side assembly" into the Windows\WinSxS system directory.
For options on how to perform a silent install read Aaron Stebner's WebLog. Here's my recipe for implementing this in an Inno Setup script: Put this code into the corresponding [files] and [run] sections. Be sure to fix Source: {#MySourceDir}\shared so that it points to vcredist_x86.exe on your system.
Source: {#MySourceDir}\shared\vcredist_x86.exe; DestDir: {tmp}; Permissions: everyone-full; Flags: ignoreversion overwritereadonly
;...additional [files] options

Filename: {tmp}\vcredist_x86.exe; Parameters: /qb!; WorkingDir: {tmp}; StatusMsg: Checking for and installing Microsoft Visual C++ Redistributable Package...; Flags: waituntilterminated
;...additional [run] options
This was successfully tested on Windows XP, Vista and 7 with a simple wx application - a stoichiometric calculator. You can download the full source here.