After installing the x64 version of Python 2.5.1 via the MSI file on python.org, I noticed most of the registry keys are "missing". Further investigation shows they aren't actually missing, but have simply been "virtualized", so they actually appear under the Wow6432Node key. This Wow6432Node key is used by 32bit programs running on a 64bit OS. Ironically, this means that a 32 bit Python can open HKLM\Software\Python - the OS virtualizes that request to the Wow3264Node tree. However, a 64 bit Python (ie, the very Python that was installed by the MSI) fails to open that key - no vistualization occurs and as the key specified does not exist, we fail. For example: This is the Python 2.5 installed by the MSI installer: Python 2.5.1 (r251:54863, Apr 18 2007, 09:02:36) [MSC v.1400 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information.
import _winreg _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, "Software\\Python\\PythonCore") Traceback (most recent call last): File "<stdin>", line 1, in <module> WindowsError: [Error 2] The system cannot find the file specified
But if I use a 32bit version of Python: Python 2.5.1 (release25-maint, Jun 4 2007, 23:00:11) [MSC v.1310 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information.
import _winreg _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, "Software\\Python\\PythonCore")
It works. I'm afraid my knowledge of MSI is very limited, so I'm not sure where to start. One thing I did notice is that msilib\__init__.py has a variable 'Win64' set, hard-coded to 0 - but I've no idea if it is relevant. Presumably it is relevant to *something*, otherwise it would not have been created - but its unclear when and how this should be set to 1, and if this should concern people trying to use bdist_msi to create x64 extension packages - but for now, let's just stick with the topic at hand - the registry keys set by the installer. Any clues? Thanks, Mark
On 7/12/07, Mark Hammond
I'm afraid my knowledge of MSI is very limited, so I'm not sure where to start. One thing I did notice is that msilib\__init__.py has a variable 'Win64' set, hard-coded to 0 - but I've no idea if it is relevant. Presumably it is relevant to *something*, otherwise it would not have been created - but its unclear when and how this should be set to 1, and if this should concern people trying to use bdist_msi to create x64 extension packages - but for now, let's just stick with the topic at hand - the registry keys set by the installer.
Per the requirements documented at http://msdn2.microsoft.com/En-US/library/aa372396.aspx, the behavior you describe is expected for a 32-bit installer. (To install files and registry to 64-bit locations, the Template Summary must include Intel64 or x64 depending on which architecture, and the component must be marked as 64-bit). I'm not familiar with how msilib is invoked to create the MSI files in question, but it does look like setting Win64 to 1 at an early enough time would cause an Intel64 installer to be built, along with entirely 64-bit components. This wouldn't work for x64 machines, and all components being 64-bit may be incorrect: potentially the 64-bit installer should have some 32-bit components. -- Michael Urman
Per the requirements documented at http://msdn2.microsoft.com/En-US/library/aa372396.aspx, the behavior you describe is expected for a 32-bit installer.
Agreed - but unless I'm missing something, this release is not expected to be a 32bit installer.
(To install files and registry to 64-bit locations, the Template Summary must include Intel64 or x64 depending on which architecture, and the component must be marked as 64-bit).
I'm not familiar with how msilib is invoked to create the MSI files in question, but it does look like setting Win64 to 1 at an early enough time would cause an Intel64 installer to be built, along with entirely 64-bit components. This wouldn't work for x64 machines,
Why wouldn't it work for x64 machines? Is it simply because msilib only handles Intel64 when that flag is set?
and all components being 64-bit may be incorrect: potentially the 64-bit installer should have some 32-bit components.
What 32bit components should a 64bit build of Python include? Perhaps you mean *could* - but IIUC, there is no intention to release 32bit and 64bit versions of Python in a single package (and further, IIUC, no intent on supporting a 32bit and 64bit installation on the same machine, regardless of packaging) I'm afraid its not clear to me if you are agreeing with me (ie, that the registry keys are incorrect), or disagreeing with me (the keys are what you would expect a correct x64 install to create)? I think you are agreeing, but sounding a caution that it might not be trivial to fix, but I would like to be sure... Cheers, Mark
On 7/12/07, Mark Hammond
Why wouldn't it work for x64 machines? Is it simply because msilib only handles Intel64 when that flag is set?
Right - it sets the template summary to include Intel64, not x64. Furthermore only one architecture may be set in the template summary, so an installer may be only one of i386, x64, and Intel64 (although the latter are assumed to also be able to run i386 binaries).
What 32bit components should a 64bit build of Python include? Perhaps you mean *could* - but IIUC, there is no intention to release 32bit and 64bit versions of Python in a single package (and further, IIUC, no intent on supporting a 32bit and 64bit installation on the same machine, regardless of packaging)
Agreed. I was just making clear that I'm not familiar with what the MSI includes, and whether any of the components in a 64-bit install should be 32-bit or not. With the msilib code as is, it appears to be all or nothing, or rely on tweaking a global between calls to start_component.
I'm afraid its not clear to me if you are agreeing with me (ie, that the registry keys are incorrect), or disagreeing with me (the keys are what you would expect a correct x64 install to create)? I think you are agreeing, but sounding a caution that it might not be trivial to fix, but I would like to be sure...
The former, with hints of caution: it appears the unused 64-bit code paths of msilib were created to best serve under incorrect assumptions. With what the code would create (with or without Win64 set), it will not generate the 64-bit registry keys that the 64-bit program will access. With Win64 set it will not even install except on an Itanium system. If you just want to get to the keys it currently sets, there should be an override parameter that causes the registry API to read the 32-bit keys even in a 64-bit process, but I'm not familiar with using _winreg. If there's interest and I can get pointers to where the MSI files are built, I can look into patching it. I don't have a convenient 64-bit Windows machine around to test any changes, though. -- Michael Urman
On Friday, 13 July 2007, Michael Urman wrote:
Furthermore only one architecture may be set in the template summary, so an installer may be only one of i386, x64, and Intel64 (although the latter are assumed to also be able to run i386 binaries).
I suspect I'm still missing something here. The title of the page you referenced before is "Using 64-Bit Windows Installer Packages" - I suspect that is different than a 32-Bit installer package installing a 64bit program!
Agreed. I was just making clear that I'm not familiar with what the MSI includes, and whether any of the components in a 64-bit install should be 32-bit or not. With the msilib code as is, it appears to be all or nothing, or rely on tweaking a global between calls to start_component.
Yes - that is a bit of a shame, as having 32bit components would allow more flexibility (eg, allow a 64bit install of Python to work with an IIS configured for 32bit extensions), but that's something we can deal with later if necessary.
If you just want to get to the keys it currently sets, there should be an override parameter that causes the registry API to read the 32-bit keys even in a 64-bit process, but I'm not familiar with using _winreg.
using _winreg is (almost) like using the API directly. RegDisable[/Enable]ReflectionKey appears to let the 32bit process see the real keys - I'm not aware of how 64bit apps would enable that reflection, but it probably doesn't really matter for our purposes. In case anyone is interested, I just made a patch to _winreg.c adding these 2 functions (http://python.org/sf/1753245) in case anyone would like to review it.
If there's interest and I can get pointers to where the MSI files are built, I can look into patching it. I don't have a convenient 64-bit Windows machine around to test any changes, though.
I think Tools\msi is what you are looking for, but hopefully Martin will chime in. I'm more than happy to help test. Cheers, Mark
I suspect I'm still missing something here. The title of the page you referenced before is "Using 64-Bit Windows Installer Packages" - I suspect that is different than a 32-Bit installer package installing a 64bit program!
Right. You cannot easily have a 32-bit installer install 64-bit programs. That will normally not work, as Windows will silently redirect all registry keys to the Wow6432Node, so it won't "see" the registry keys that the Win64 program sees. The only way to "see" the same keys as a 64-bit process would do is to specify KEY_WOW64_64KEY when opening the key.
Agreed. I was just making clear that I'm not familiar with what the MSI includes, and whether any of the components in a 64-bit install should be 32-bit or not. With the msilib code as is, it appears to be all or nothing, or rely on tweaking a global between calls to start_component.
Yes - that is a bit of a shame, as having 32bit components would allow more flexibility (eg, allow a 64bit install of Python to work with an IIS configured for 32bit extensions), but that's something we can deal with later if necessary.
Can you elaborate? It's incorrect for a Win64 installer to make the executable components Win32. A 64 bit pythonxy.dll cannot work in a 32-bit IIS - it's a different instruction set. That's not something that you can fix by just installing things differently.
using _winreg is (almost) like using the API directly. RegDisable[/Enable]ReflectionKey appears to let the 32bit process see the real keys - I'm not aware of how 64bit apps would enable that reflection, but it probably doesn't really matter for our purposes.
They can specify KEY_WOW64_32KEY. Regards, Martin
Martin quoting me:
Yes - that is a bit of a shame, as having 32bit components would allow more flexibility (eg, allow a 64bit install of Python to work with an IIS configured for 32bit extensions), but that's something we can deal with later if necessary.
Can you elaborate?
As you mention, 64 and 32bit programs use different instruction sets. Therefore, trying to use a 64bit install of Python with IIS configured to work with 32bits is not going to work. In this case, switching the configuration of IIS will require the Python user to uninstall the previous version and install a different version - but some sites may end up in a dilemma here - they may be *forced* to use IIS in 32bit mode due to no 64bit port for a tool they need, but simultaneously desire a 64bit build of Python for other tasks on that same box.
It's incorrect for a Win64 installer to make the executable components Win32.
Right - I got the impression from Micheal that it was possible for 32bit components to be installed in a 64bit install, but I don't profess to know anything about this.
A 64 bit pythonxy.dll cannot work in a 32-bit IIS - it's a different instruction set. That's not something that you can fix by just installing things differently.
Exactly - which is why I'm suggesting that not "allowing" 64bit and 32bit versions of Python to be installed on the same box will cause inconvenience for some people. I agree such people will be in the minority, and their requirements are not clear, so I'm not pushing for a change of policy here.
using _winreg is (almost) like using the API directly. RegDisable[/Enable]ReflectionKey appears to let the 32bit process see the real keys - I'm not aware of how 64bit apps would enable that reflection, but it probably doesn't really matter for our purposes.
They can specify KEY_WOW64_32KEY.
Ah - thanks. Cheers, Mark
As you mention, 64 and 32bit programs use different instruction sets. Therefore, trying to use a 64bit install of Python with IIS configured to work with 32bits is not going to work. In this case, switching the configuration of IIS will require the Python user to uninstall the previous version and install a different version - but some sites may end up in a dilemma here - they may be *forced* to use IIS in 32bit mode due to no 64bit port for a tool they need, but simultaneously desire a 64bit build of Python for other tasks on that same box.
IIUC, you want the AMD64 installer also deploy 32-bit pythonxy.dll etc. That's a challenge, of course: how would you install the 32-bit extension modules so that they don't interfere with the 64-bit ones?
Right - I got the impression from Micheal that it was possible for 32bit components to be installed in a 64bit install, but I don't profess to know anything about this.
That is true. However, there really isn't anything special about a 32bit component: the only difference is that Installer turns on file and registry redirection when installing that component. You are free to put 32-bit executables into 64-bit components just fine. (A "component" in MSI is a group of files and registry keys that is installed together). Regards, Martin
On 7/13/07, Mark Hammond
On Friday, 13 July 2007, Michael Urman wrote: I suspect I'm still missing something here. The title of the page you referenced before is "Using 64-Bit Windows Installer Packages" - I suspect that is different than a 32-Bit installer package installing a 64bit program!
I haven't worked with it enough to know all the intracacies, but the short of what I know is if your template is i386, you can only install to 32-bit locations. If it is x64 or Intel64, then you can only install on machines of those architectures, and the 64-bit locations become available to components marked as 64-bit.
using _winreg is (almost) like using the API directly. RegDisable[/Enable]ReflectionKey appears to let the 32bit process see the real keys - I'm not aware of how 64bit apps would enable that reflection, but it probably doesn't really matter for our purposes. In case anyone is interested, I just made a patch to _winreg.c adding these 2 functions (http://python.org/sf/1753245) in case anyone would like to review it.
http://msdn2.microsoft.com/en-us/library/aa384129.aspx describes the KEY_WOW64_64KEY and KEY_WOW64_32KEY flags, allowing explicit access to either set from either type of application.
I think Tools\msi is what you are looking for, but hopefully Martin will chime in. I'm more than happy to help test.
Thanks, and I see he has, and perhaps I've been looking at an incorrect file... -- Michael Urman
Michael Urman schrieb:
On 7/12/07, Mark Hammond
wrote: Why wouldn't it work for x64 machines? Is it simply because msilib only handles Intel64 when that flag is set?
Right - it sets the template summary to include Intel64, not x64.
You might be looking at the wrong version. In Python 2.5, it also sets it to x64, if the PE machine type is 0x8664.
Furthermore only one architecture may be set in the template summary, so an installer may be only one of i386, x64, and Intel64 (although the latter are assumed to also be able to run i386 binaries).
Right. That's why I provide three installers.
Agreed. I was just making clear that I'm not familiar with what the MSI includes, and whether any of the components in a 64-bit install should be 32-bit or not. With the msilib code as is, it appears to be all or nothing, or rely on tweaking a global between calls to start_component.
That's correct. I'm also uncertain what precisely the Win64 flag on a component means, according to http://msdn2.microsoft.com/EN-US/library/aa368007.aspx msidbComponentAttributes64bit means # Set this bit to mark this as a 64-bit component. This attribute # facilitates the installation of packages that include both 32-bit and # 64-bit components. If this bit is not set, the component is registered # as a 32-bit component. # # If this is a 64-bit component replacing a 32-bit component, set this # bit and assign a new GUID in the ComponentId column. When I started to work on this, I found that not setting the Win64 bit at all "does not work", although I forgot the details what precisely failed. I found some articles in the net that suggest that this flag turns off redirection, e.g. http://blogs.msdn.com/heaths/archive/2006/04/14/avoid-overwriting-files-in-a... As we don't want any redirection, setting the flag on all components should be correct.
The former, with hints of caution: it appears the unused 64-bit code paths of msilib were created to best serve under incorrect assumptions. With what the code would create (with or without Win64 set), it will not generate the 64-bit registry keys that the 64-bit program will access.
Why do you say that? What registry keys do you think it creates, and what registry keys do you think it should create instead? There are no "64-bit registry keys" on Windows; Win64 only has "normal registry keys" and "32-bit (i.e. redirected) registry keys".
With Win64 set it will not even install except on an Itanium system.
I always test whether the AMD 64 binary installs correctly before releasing it.
If you just want to get to the keys it currently sets, there should be an override parameter that causes the registry API to read the 32-bit keys even in a 64-bit process, but I'm not familiar with using _winreg.
If there's interest and I can get pointers to where the MSI files are built, I can look into patching it. I don't have a convenient 64-bit Windows machine around to test any changes, though.
You don't need to provide patches - just tell me what's wrong with the MSI file. I.e. look at it in orca, correct it so that it works correctly, then report what changes you made. Regards, Martin
On 7/13/07, "Martin v. Löwis"
Michael Urman schrieb:
Right - it sets the template summary to include Intel64, not x64.
You might be looking at the wrong version. In Python 2.5, it also sets it to x64, if the PE machine type is 0x8664.
I've looked most closely at http://svn.python.org/view/python/trunk/Lib/msilib/__init__.py?rev=47280&view=auto, and from there not even full readings yet, just searching for Win64 to see what the flag did. No doubt I have missed several intracacies.
As we don't want any redirection, setting the flag on all components should be correct.
It may well be fine for the Python installers. Without the flag, locations such as the 64-bit folder destinations resolve to the 32-bit redirected locations, and the registry resolves to the 32-bit reflected registry. The former isn't particularly helpful in any case I can think of (as the non 64-bit locations are available anyway), but the latter could be important if an 64-bit install needs to set 32-bit registry keys.
The former, with hints of caution: it appears the unused 64-bit code paths of msilib were created to best serve under incorrect assumptions. With what the code would create (with or without Win64 set), it will not generate the 64-bit registry keys that the 64-bit program will access.
Why do you say that? What registry keys do you think it creates, and what registry keys do you think it should create instead?
Perhaps it's my reading the wrong version (the one I linked above doesn't even have the string x64), or my assumption that msilib would target a more general use case than pure 64-bit / pure 32-bit installers. Or I missed the easy way to interleave 64 and 32-bit components.
There are no "64-bit registry keys" on Windows; Win64 only has "normal registry keys" and "32-bit (i.e. redirected) registry keys".
I find that nomenclature distinction to be more confusing than referring to them "incorrectly" :)
I always test whether the AMD 64 binary installs correctly before releasing it.
And I ran no tests at all, so I defer to you here.
You don't need to provide patches - just tell me what's wrong with the MSI file. I.e. look at it in orca, correct it so that it works correctly, then report what changes you made.
That's even easier then, if anything's actually wrong. I'll find some time this weekend to look at it and report back. Would the one at the following URL be the correct one to verify? http://www.python.org/ftp/python/2.5.1/python-2.5.1.amd64.msi (linked from http://www.python.org/download/) -- Michael Urman
On 7/13/07, Michael Urman
That's even easier then, if anything's actually wrong. I'll find some time this weekend to look at it and report back. Would the one at the following URL be the correct one to verify?
http://www.python.org/ftp/python/2.5.1/python-2.5.1.amd64.msi (linked from http://www.python.org/download/)
Assuming this is the right file, the cause of the behavior Mark reported is pretty clear. While the template summary is indeed x64, the attributes on the registry components are all 4 instead of 256 | 4, so they are placed in the 32-bit reflected registry. I don't know if this is desirable for some other reason. -- Michael Urman
Assuming this is the right file, the cause of the behavior Mark reported is pretty clear. While the template summary is indeed x64, the attributes on the registry components are all 4 instead of 256 | 4, so they are placed in the 32-bit reflected registry. I don't know if this is desirable for some other reason.
I found the same thing, and put a corrected installer at http://www.dcl.hpi.uni-potsdam.de/home/loewis/python-2.5.1.amd64.msi Mark, can you please report whether that fixes your problem? Regards, Martin
Martin:
Assuming this is the right file, the cause of the behavior Mark reported is pretty clear. While the template summary is indeed x64, the attributes on the registry components are all 4 instead of 256 | 4, so they are placed in the 32-bit reflected registry. I don't know if this is desirable for some other reason.
I found the same thing, and put a corrected installer at
http://www.dcl.hpi.uni-potsdam.de/home/loewis/python-2.5.1.amd64.msi
Mark, can you please report whether that fixes your problem?
It does indeed - thank you guys! Mark
Hi Martin,
I found the same thing, and put a corrected installer at
http://www.dcl.hpi.uni-potsdam.de/home/loewis/python-2.5.1.amd64.msi
Is there any intention to update the msi at python.org? Alternatively, can I point people at the above file? I've a .msi created by bdist_msi that works only with the corrected version and I'm wondering the best way to get people to test it... Cheers, Mark.
Hi Martin,
I found the same thing, and put a corrected installer at
http://www.dcl.hpi.uni-potsdam.de/home/loewis/python-2.5.1.amd64.msi
Is there any intention to update the msi at python.org?
No. I would have to bump the version number for that, which I cannot do - it will need to wait for 2.5.2.
Alternatively, can I point people at the above file?
That's certainly fine. I can leave the file in place at least until 2.5.2 is released (although I will eventually remove it, to reduce confusion). Regards, Martin
I've looked most closely at http://svn.python.org/view/python/trunk/Lib/msilib/__init__.py?rev=47280&view=auto, and from there not even full readings yet, just searching for Win64 to see what the flag did. No doubt I have missed several intracacies.
Ah, ok. This should get fixed, but it isn't use to create the installer. Instead, look at http://svn.python.org/view/python/trunk/Tools/msi/msilib.py?rev=55245&view=markup
Perhaps it's my reading the wrong version (the one I linked above doesn't even have the string x64), or my assumption that msilib would target a more general use case than pure 64-bit / pure 32-bit installers.
Why should it? I have yet to see a use case for that.
That's even easier then, if anything's actually wrong. I'll find some time this weekend to look at it and report back. Would the one at the following URL be the correct one to verify?
http://www.python.org/ftp/python/2.5.1/python-2.5.1.amd64.msi (linked from http://www.python.org/download/)
Indeed. Regards, Martin
I'm not familiar with how msilib is invoked to create the MSI files in question, but it does look like setting Win64 to 1 at an early enough time would cause an Intel64 installer to be built, along with entirely 64-bit components. This wouldn't work for x64 machines, and all components being 64-bit may be incorrect: potentially the 64-bit installer should have some 32-bit components.
There are several places where "64-bitness" need to be considered: you need to set the architecture of the entire MSI file, and the installer sets it to "x64" ("Intel64" means Itanium). In addition, you can set the Win64 bit on components, and msilib sets it on all components, AFAIK. Regards, Martin
I'm afraid my knowledge of MSI is very limited, so I'm not sure where to start. One thing I did notice is that msilib\__init__.py has a variable 'Win64' set, hard-coded to 0 - but I've no idea if it is relevant. Presumably it is relevant to *something*, otherwise it would not have been created - but its unclear when and how this should be set to 1, and if this should concern people trying to use bdist_msi to create x64 extension packages - but for now, let's just stick with the topic at hand - the registry keys set by the installer.
Any clues?
Please take a look at msilib.set_arch_from_file. This takes an executable file, determines the processor architecture, and then sets both MSI type (the PID_TEMPLATE SummaryInformation field), and the Win64 variable, which should cause all components to become Win64 components (i.e. flag 256 being set). Regards, Martin
participants (3)
-
"Martin v. Löwis"
-
Mark Hammond
-
Michael Urman