[Zope-dev] Windows Installer for Zope 2.9+
Tim Peters
tim.peters at gmail.com
Fri Dec 9 22:19:57 EST 2005
...
[Sidnei da Silva]
> Simplifying a lot what the existing Zope 2 installer does, it
> basically creates a 'software home', a default 'instance home' and
> registers the services. All but the first part is done manually for
> Zope 3, so I can see the lack of glow there.
There's also that Zope2 sticks Python inside of Zope, but Zope3 sticks
Zope inside of Python. A consequence is that you can't install more
than one instance of Zope3 under a single Windows account, but can
install any number of Zope2s. In the other direction, it's always a
puzzle for Zope2 Windows users to figure out how to give their Zope
access to packages installed in their (own, separate) Python. For
Zope3 that's a no-brainer.
> 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.)
> 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.
> 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>.
> 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.
> 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.
More information about the Zope-Dev
mailing list