Hi All, I really need to be able to do a silent install of the pywin32 package for python2.7, so I started looking at the distutils bdist_msi option, to see if I could get that working for pywin32. Although I *was eventually able to do so,* I ran into several problems that I had to work around in the process:
1) I couldn't build from the latest source version (218). This is because the downloadable pywin32-218.zip file is either incomplete or inconsistent, because the win32\src\PerfMon directory no longer includes perfutil.h, but the code therein attempts to include it. (See bug https://sourceforge.net/p/pywin32/bugs/647/.) 2) I was able to successfully build the source tree for pywin32-217, but when I ran with the bdist_msi option, it complained: Executing post install script... creating dist Traceback (most recent call last): File "setup.py", line 2435, in [...] File "c:\Python27\lib\distutils\command\bdist_msi.py", line 232, in run sversion = "%d.%d.%d" % StrictVersion(version).version File "c:\Python27\lib\distutils\version.py", line 40, in init self.parse(vstring) File "c:\Python27\lib\distutils\version.py", line 107, in parse raise ValueError, "invalid version number '%s'" % vstring ValueError: invalid version number '217' (Bug https://sourceforge.net/p/pywin32/bugs/648/.) It turns out that this error is thrown because the msi installer mechanism requires the use of the 'StrictVersion' class in the distutils package, and that disallows a single integer version number. Similarly, the pywin32_version string used to compile the sources (eg. 2.7.217.0) is also illegal, because it only allows an Major.Minor[.build][abN] structure. Since the dist object specified in the setup.py just uses the build_id (eg. '217') as the version, this makes the distutils stuff choke when trying to use the bdist_msi option. To work around this, I modified the setup.py script to add a pywin32_msi_version string, which I set to: build_id_patch = build_id if not "." in build_id_patch: build_id_patch = build_id_patch + ".0" pywin32_version="%d.%d.%s" % (sys.version_info[0], sys.version_info[1], build_id_patch) + pywin32_msi_version = "%d.%d.%s" % (sys.version_info[0], sys.version_info[1], build_id) (That is, exclude the .0 from the string, so that it was just '2.7.217'. This seemed a reasonable thing to do, as I've never seen a "patch" number on any pywin32 version, and the rest seemed appropriate, but I don't know if Mark Hammond would agree, and if there ever was a patch number, this would not work.) I then also modified the dist object's setup construction, thusly: dist = setup(name="pywin32", < version=str(build_id), --- > version=str(pywin32_msi_version), description="Python for Window Extensions", With these minor changes, I was then able to successfully build the msi. However, I have no idea of the possible other consequences of this modification, vis-à-vis the other distutils bdist methods, and so am not sure if this would be an appropriate general fix. However, there was yet another problem: 3) On actually trying to use the resulting .msi, the postinstall script failed. It turns out that there is a bug in the distutils build_msi.py file; although the documentation claims that it supplies the -install and -remove arguments to any postinstall scripts for their respective invocation, it does not, in fact, currently do this. As a result, the pywin32_postinstall.py just generated a usage message because it was run without arguments, and thus didn't work properly, either for install or remove. It turns out that this distutils bug was reported back in August of 2012, and a patch has even been supplied (see http://bugs.python.org/issue15797.) When I applied the supplied patch, and rebuilt my msi, it properly ran the postinstall script, and (as far as I can tell) the resulting install works perfectly! (And there was much rejoicing... yea...) So: The reasons for my post to this forum: 1) Is the change I made to the version string used in the dist construction appropriate? If not, what would be the appropriate version to use? 2) Can this version be used for both the .exe and the .msi build methods, or, if not, is there a way to conditionally set this based on which type of build is being attempted? 3) The patch for distutils was submitted in August of 2012, but, AFAICT, has not been incorporated into the 2.7.x distutils source; is there a way to expedite that? 4) Would it be possible to take all of this into account, verify that I'm not missing anything subtle, and generate "official" .msi files for pywin32, since this is all targeted *for Microsoft systems,* after all... ;) Thanks in advance, /Will Sadkin _______________________________________________ python-win32 mailing list python-win32@python.org http://mail.python.org/mailman/listinfo/python-win32