[mod_python] Bug in Windows installation

David Fraser davidf at sjsoft.com
Mon Apr 26 09:45:21 EST 2004


Thanks for posting this, I created the Windows installer script and one 
of my colleagues noticed this too, so we prepared a modified version.
I have attached the modified win32_postinstall.py script ; and I have a 
rebuilt installer at 
This also contains a fix for the attachment filetype problem.
Please test and let me know if this fixes your problem


PS Grisha, is there time now to start getting this stuff into CVS, as it 
would be better management-wise? :-)

Eddie Diener wrote:

> Mod_python's postinstall script assumes that the Apache key in the 
> Windows registry is in HKLM. However if one installs Apache Web Server 
> on Windows and chooses to install for the current user in order to 
> start Apache manually from the Console Window, the entry is under 
> HKCU. Because of this an exception is thrown in the script when 
> attempting to open HKLM/Apache Group/Apache and the postinstall script 
> never finishes.
> Here is the exception trace:
> Traceback (most recent call last):
> File "H:\UTILIT~1\Python23\Scripts\win32_postinstall.py", line 86, in ?
> apachediroptions = getApacheDirOptions()
> File "H:\UTILIT~1\Python23\Scripts\win32_postinstall.py", line 45, in
> getApacheDirOptions
> apachekey = regkey(win32con.HKEY_LOCAL_MACHINE, 
> "Software").childkey("Apache
> Group").childkey("Apache")
> File "H:\UTILIT~1\Python23\Scripts\win32_postinstall.py", line 34, in
> childkey
> return regkey(self.key, subkeyname)
> File "H:\UTILIT~1\Python23\Scripts\win32_postinstall.py", line 32, in
> __init__
> self.key = win32api.RegOpenKey(parent, subkeyname)
> pywintypes.error: (2, 'RegOpenKeyEx', 'The system cannot find the file
> specified.')
> Exception exceptions.AttributeError: "regkey instance has no attribute
> 'key'" in <bound method regkey.__del__ of <__main__.regkey instance at
> 0x011C8468>> ignored
> *** run_installscript: internal error 0xFFFFFFFF ***
> A workaround is to temporarily duplicate the Apache registry keys from 
> HKCU to HKLM and add the ServerRoot key value, poinitng it to the root 
> directory where Apache is installed. The installing mod_python works OK.
>Mod_python mailing list
>Mod_python at modpython.org

-------------- next part --------------
 # Copyright 2004 Apache Software Foundation
 #  Licensed under the Apache License, Version 2.0 (the "License");
 #  you may not use this file except in compliance with the License.
 #  You may obtain a copy of the License at
 #      http://www.apache.org/licenses/LICENSE-2.0
 #  Unless required by applicable law or agreed to in writing, software
 #  distributed under the License is distributed on an "AS IS" BASIS,
 #  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 # Originally developed by Gregory Trubetskoy.
 # $Id: win32_postinstall.py,v 1.5 2004/02/16 19:47:27 grisha Exp $
 # this script runs at the end of windows install

import sys, os, shutil
import distutils.sysconfig

def getApacheDirOptions():
    """find potential apache directories in the registry..."""
        import win32api, win32con
        class nullregkey:
            """a registry key that doesn't exist..."""
            def childkey(self, subkeyname):
                return nullregkey()
            def subkeynames(self):
                return []
            def getvalue(self, valuename):
                raise AttributeError("Cannot access registry value %r: key does not exist" % (valuename))
        class regkey:
            """simple wrapper for registry functions that closes keys nicely..."""
            def __init__(self, parent, subkeyname):
               self.key = win32api.RegOpenKey(parent, subkeyname)
            def childkey(self, subkeyname):
                   return regkey(self.key, subkeyname)
               except win32api.error:
                   return nullregkey()
            def subkeynames(self):
               numsubkeys = win32api.RegQueryInfoKey(self.key)[0]
               return [win32api.RegEnumKey(self.key, index) for index in range(numsubkeys)]
            def getvalue(self, valuename):
                   return win32api.RegQueryValueEx(self.key, valuename)
               except win32api.error:
                   raise AttributeError("Cannot access registry value %r" % (valuename))
            def __del__(self):
               if hasattr(self, "key"):
    except ImportError:
        return {}
    versions = {}
    hklm_key = regkey(win32con.HKEY_LOCAL_MACHINE, "Software").childkey("Apache Group").childkey("Apache")
    hkcu_key = regkey(win32con.HKEY_CURRENT_USER, "Software").childkey("Apache Group").childkey("Apache")
    for apachekey in (hklm_key, hkcu_key):
        for versionname in apachekey.subkeynames():
                serverroot = apachekey.childkey(versionname).getvalue("ServerRoot")
            except AttributeError:
            versions[versionname] = serverroot[0]
    return versions

def askForApacheDir(apachediroptions):
    # try to ask for Apache directory
    if len(apachediroptions) > 0:
        # get the most recent version...
        versionnames = apachediroptions.keys()
        initialdir = apachediroptions[versionnames[-1]]
        initialdir="C:/Program Files/Apache Group/Apache2"
    # TODO: let the user select the name from a list, or click browse to choose...
        from tkFileDialog import askdirectory
        from Tkinter import Tk
        root = Tk()
        path = askdirectory(title="Where is Apache installed?",
                            mustexist=1, master=root)
        return path
    except ImportError:
            from win32com.shell import shell
            pidl, displayname, imagelist = shell.SHBrowseForFolder(0, None, "Where is Apache installed?")
            path = shell.SHGetPathFromIDList(pidl)
            return path
        except ImportError:
            return ""

# if we're called during removal, just exit
if len(sys.argv) == 0 or (len(sys.argv) > 1 and sys.argv[1] != "-remove"):

    mp = os.path.join(distutils.sysconfig.get_python_lib(), "mod_python_so.pyd")

    apachediroptions = getApacheDirOptions()

    apachedir = askForApacheDir(apachediroptions)

    if apachedir:

        # put mod_python.so there
        shutil.copy2(mp, os.path.join(apachedir, "modules", "mod_python.so"))

        print """Important Note for Windows users, PLEASE READ!!!

        1. This script does not attempt to modify Apache configuration,
           you must do it manually:

           Edit %s,
           find where other LoadModule lines are and add this:
                LoadModule python_module modules/mod_python.so

        2. Now test your installation using the instructions at this link:

        """ % os.path.join(apachedir, "conf", "httpd.conf")


        print """Important Note for Windows users, PLEASE READ!!!

        1. It appears that you do not have Tkinter installed,
           which is required for a part of this installation.
           Therefore you must manually take
           and copy it to your Apache modules directory.

        2. This script does not attempt to modify Apache configuration,
           you must do it manually:

           Edit %s,
           find where other LoadModule lines and add this:
                LoadModule python_module modules/mod_python.so

        3. Now test your installation using the instructions at this link:

        """ % (mp, os.path.join(apachedir, "conf", "httpd.conf"))

More information about the Mod_python mailing list