[Zope-dev] Windows Installer for Zope 2.9+

Sidnei da Silva sidnei at enfoldsystems.com
Fri Dec 9 22:40:10 EST 2005


On Fri, Dec 09, 2005 at 10:19:57PM -0500, Tim Peters wrote:
| > Supposing there is a existing python installation, how difficult is it
| > to get a distutils-based windows installer to be extracted to a random
| > directory outside site-packages?
| 
| distutils has no support for that.
| 
| > My guess is that it's basically unzip it.
| 
| What are you trying to accomplish?  (I know you're trying to push code
| into some directory other than under Lib/site-packages, but I don't
| know which code or why.)

That would be Zope's code.

| > If that's the case, we can simplify the Zope 2 inno installer to:
| >
| > 1. include a distutils-based windows installer for the Zope 2 source
| > 2. include some setup scripts
| >
| > Then on installation
| >
| > 1. find or install according python
| 
| Note that Zope also needs pywin32 to be installed.

Right.

| > 2. unpack the distutils-based windows installer into Program
| >   Files\Zope
| 
| OK, so you're trying to preserve that ... what?  You're neither
| sticking Python inside Zope nor Zope inside Python?
| 
| BTW,  _how_ do you unpack this at install time?  You can't, for
| example, assume that a Windows box has any unzip utility (let alone
| some specific one).  So this part would probably be simpler if you
| point Inno at a Zope tree and let _it_ package it and unpack it. 
| Maybe the way to get such a tree is to build a distutils installer for
| Zope and run it on your own box, pointing Inno at the tree it creates,
| then throw the distutils installer away <0.3 wink>.

Yeah, why not. That would work, I think.

| > 3. create a default 'instance home', pointing to the installed python
| 
| An instance home _certainly_ doesn't belong inside the user's Python
| -- but maybe I don't know what you mean by these words (I'm probably
| misreading "pointing to").  It should be possible to create any number
| of distinct instance homes.

I mean't 'using the user's installed python'.

| > 4. register the services
| >
| > Steps 2-4 are reasonably simple to me, the tricky one is 1.
| 
| Maybe somone will hit me for this ;-), but we have Inno code for #1 in
| one of our other installers.  It goes like this:
| 
| [Code]
| var
|     // Path to the user's Python installation, found from the registry.
|     // Procedure SetPythonInstallPath deduces this.
|     gPythonInstallPath: String;
| 
| function InitializeSetup(): boolean;
| begin
|     gPythonInstallPath := '';   // don't know yet
|     Result := True;
| end;
| 
| ...
| 
| // Look up Python's install path in the registry.  Use HKCU first, because
| // a "user-only" instance is supposed to take precedence.  If no Python is
| // installed, this will leave gPythonInstallPath as an empty string.
| procedure SetPythonInstallPath();
| begin
|     RegQueryStringValue(HKCU,
|         'Software\Python\PythonCore\2.4\InstallPath',
|          '',
|          gPythonInstallPath);
|     if gPythonInstallPath = '' then // not in HKCU, so try HKLM
|         RegQueryStringValue(HKLM,
|             'Software\Python\PythonCore\2.4\InstallPath',
|             '',
|             gPythonInstallPath);
| end;
| 
| // Expose gPythonInstallPath to {code:...} clauses.
| function GetPythonDir(Default: String): String;
| begin
|     Result := gPythonInstallPath;
| end;
| 
| ...
| 
| procedure SetupDependencies();
| var
|     PythonSetupFile: String;
|     PyWin32SetupFile: String;
| ...
| begin
|     PythonSetupFile := 'python-2.4.2.msi';
|     PyWin32SetupFile := 'pywin32-205.win32-py2.4.exe';
| ...
|     // Setup python, unless it is already installed.
|     SetPythonInstallPath();
|     if gPythonInstallPath = '' then begin
|         if not ShellExec('open', ExpandConstant('{tmp}\files\' +
| PythonSetupFile),
|                          '', '', SW_SHOW, ewWaitUntilTerminated, ErrorCode) then
|                FatalError('Unable to install python');
|         // Try again to find the install path.
|         SetPythonInstallPath();
|         if gPythonInstallPath = '' then
|             // This shouldn't happen ... but if it does, we dare not leave this
|             // variable empty:  the installer blithely goes on to copy files
|             // into the Windows system32 directory if we do.  That should never
|             // be allowed.
|             gPythonInstallPath := ExpandConstant('{tmp}\NoPython\');
|     end;
| 
|     // Setup pywin32
|     if not Exec(ExpandConstant('{tmp}\files\' + PyWin32SetupFile), '', '',
|                      SW_SHOW, ewWaitUntilTerminated, ErrorCode) then
|                 FatalError('Unable to install PythonWin32');
| 
| ...
| 
| The key is that the Python installer creates a registry entry, so you
| can guess whether Python is installed by looking at that.  Note that
| this Inno code doesn't try to do silent installs -- and it always runs
| the pywin32 installer.

Looks great. That will be very useful if I ever get around fixing the
Zope 2 installer, which I hope I will.

-- 
Sidnei da Silva
Enfold Systems, LLC.
http://enfoldsystems.com


More information about the Zope-Dev mailing list