Title: bdist_msi package duplicates everything to a bogus location when run with /passive or /q
Type: behavior Stage: resolved
Components: Distutils, Library (Lib), Windows Versions: Python 3.6, Python 3.5, Python 2.7
Status: closed Resolution: out of date
Dependencies: Superseder:
Assigned To: Nosy List: Ivan.Pozdeev, dstufft, eric.araujo, paul.moore, steve.dower, tim.golden, zach.ware
Priority: normal Keywords:

Created on 2016-04-17 16:12 by Ivan.Pozdeev, last changed 2021-02-03 18:26 by steve.dower. This issue is now closed.

File name Uploaded Description Edit
mercurial-3.7.3.log.gz Ivan.Pozdeev, 2016-04-17 16:11 MSI debug log for a fauty installation. .msi was generated with bdist_msi with issue #26786 fixed
Messages (2)
msg263615 - (view) Author: Ivan Pozdeev (Ivan.Pozdeev) * Date: 2016-04-17 16:11
First, the background information so you understand what I am talking about.

bdist_msi-produced packages work in the following way:

The files to install are presented as at least 3 equivalent sets (implemented as Features): "Python<version>" (for Python from registry), "PythonX" (for Python from a custom location) and a hidden but always selected "Python" - a "source" set.
Files in them are linked together with DuplicateFiles, with "real" files in the "Python" set.

"Python" has the installation target set to TARGETDIR that has the default value specified as "SourceDir" (practice shows it's initially set to the root of the drive where the .msi being installed is).
The other two have default locations set to subdirectories of TARGETDIR, but PYTHON<version> is changed to the root of the installed Python early on (at AppSearch stage and custom actions just after it in both InstallUISequence and InstallExecuteSequence) if an installtion is detected.

Now, at SelectFeaturesDlg in InstallUISequence, TARGETDIR is changed to a location for one of the features selected for install (initially, "Python<version>" is selected if an installation was found). Later, as a public property, it's passed to InstallExecuteSequence, acting as the new default value.

Finally, the files are installed to TARGETDIR and _duplicated_ to locations for all other features that have been selected. So, if only one feature was selected (the common scenario), TARGETDIR is equal to its location, so no duplication takes place. If nothing was selected, everything is unpacked to the directory where the .msi is, like `tar' does. (The latter is extremely weird for an .msi but is quite in line with the logic for other types of `bdist_' packages.)


Now, the problem is:
* the aforementioned TARGETDIR switch is implemented as an event handler in the SelectFeaturesDlg dialog.
* if I run with /passive or /q, InstallUISequence isn't done, the dialog isn't shown, and the event never happens.
* so TARGETDIR remains the default, and MSI installs everything to whatever that default happened to be, then duplicates to the correct location.


To fix this, we need to somehow duplicate the Python detection and TARGETDIR switch to InstallExecuteSequence, avoiding overwriting the results of earlier actions.

Current workaround is to pass "TARGETDIR=<python root>" to msiexec.
msg386373 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2021-02-03 18:26
Distutils is now deprecated (see PEP 632) and all tagged issues are being closed. From now until removal, only release blocking issues will be considered for distutils.

If this issue does not relate to distutils, please remove the component and reopen it. If you believe it still requires a fix, most likely the issue should be re-reported at
Date User Action Args
2021-02-03 18:26:08steve.dowersetstatus: open -> closed
resolution: out of date
messages: + msg386373

stage: resolved
2016-04-17 16:53:37SilentGhostsetversions: - Python 3.2, Python 3.3, Python 3.4
2016-04-17 16:12:00Ivan.Pozdeevcreate