gh-153511: Removes Tools/msi, Tools/nuget, and legacy py.exe launcher sources (GH-153512)

This commit is contained in:
Steve Dower authored and GitHub committed 2026-07-20 22:25:12 +01:00
1 parent c7bbf040e7
commit bd315837d8
184 files changed
+389 -17781

No files matched your search

+1 -1
View File
@@ -12,7 +12,7 @@ steps:
displayName: Show layout info (${{ parameters.kind }})
- ${{ if eq(parameters.fulltest, 'true') }}:
- script: .\python.exe -m test -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 --junit-xml="$(Build.BinariesDirectory)\test-results-${{ parameters.kind }}.xml" --tempdir "$(Build.BinariesDirectory)\tmp-${{ parameters.kind }}-$(arch)" -i test_launcher
- script: .\python.exe -m test -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 --junit-xml="$(Build.BinariesDirectory)\test-results-${{ parameters.kind }}.xml" --tempdir "$(Build.BinariesDirectory)\tmp-${{ parameters.kind }}-$(arch)"
workingDirectory: $(Build.BinariesDirectory)\layout-${{ parameters.kind }}-$(arch)
displayName: ${{ parameters.kind }} Tests
env:
+1 -1
View File
@@ -19,7 +19,7 @@
*.zip binary
# Specific binary files
PC/classicAppCompat.* binary
# -- None right now --
# Text files that should not be subject to eol conversion
[attr]noeol -text
+2 -6
View File
@@ -188,12 +188,8 @@ Tools/wasm/wasi @brettcannon @emmatyping @savannahostrowski
PC/ @python/windows-team
PCbuild/ @python/windows-team
# Windows installer packages
Tools/msi/ @python/windows-team
Tools/nuget/ @python/windows-team
# Windows Launcher
PC/launcher.c @python/windows-team @vsajip
# Windows Venv launcher/redirector
PC/venvlauncher.c @python/windows-team @vsajip
# ----------------------------------------------------------------------------
-18
View File
@@ -181,22 +181,6 @@ jobs:
free-threading: ${{ matrix.free-threading }}
interpreter: ${{ matrix.interpreter }}
build-windows-msi:
# ${{ '' } is a hack to nest jobs under the same sidebar category.
name: Windows MSI${{ '' }} # zizmor: ignore[obfuscation]
needs: build-context
if: fromJSON(needs.build-context.outputs.run-windows-msi)
strategy:
fail-fast: false
matrix:
arch:
- x86
- x64
- arm64
uses: ./.github/workflows/reusable-windows-msi.yml
with:
arch: ${{ matrix.arch }}
build-macos:
name: >-
macOS
@@ -650,7 +634,6 @@ jobs:
- check-generated-files
- check-c-api-docs
- build-windows
- build-windows-msi
- build-macos
- build-ubuntu
- build-ubuntu-ssltests
@@ -671,7 +654,6 @@ jobs:
allowed-failures: >-
build-android,
build-emscripten,
build-windows-msi,
build-ubuntu-ssltests,
test-hypothesis,
cifuzz,
-4
View File
@@ -47,9 +47,6 @@ on: # yamllint disable-line rule:truthy
run-wasi:
description: Whether to run the WASI tests
value: ${{ jobs.compute-changes.outputs.run-wasi }} # bool
run-windows-msi:
description: Whether to run the MSI installer smoke tests
value: ${{ jobs.compute-changes.outputs.run-windows-msi }} # bool
run-windows-tests:
description: Whether to run the Windows tests
value: ${{ jobs.compute-changes.outputs.run-windows-tests }} # bool
@@ -73,7 +70,6 @@ jobs:
run-ubuntu: ${{ steps.changes.outputs.run-ubuntu }}
run-emscripten: ${{ steps.changes.outputs.run-emscripten }}
run-wasi: ${{ steps.changes.outputs.run-wasi }}
run-windows-msi: ${{ steps.changes.outputs.run-windows-msi }}
run-windows-tests: ${{ steps.changes.outputs.run-windows-tests }}
steps:
- name: Set up Python
@@ -1,31 +0,0 @@
name: Reusable Windows MSI
on:
workflow_call:
inputs:
arch:
description: CPU architecture
required: true
type: string
permissions:
contents: read
env:
FORCE_COLOR: 1
jobs:
build:
name: installer for ${{ inputs.arch }}
runs-on: ${{ inputs.arch == 'arm64' && 'windows-11-arm' || 'windows-2025' }}
timeout-minutes: 60
env:
ARCH: ${{ inputs.arch }}
IncludeFreethreaded: true
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Build CPython installer
run: ./Tools/msi/build.bat --doc -"${ARCH}"
shell: bash
+1 -2
View File
@@ -50,7 +50,7 @@ gmon.out
*.exe
# Ignore core dumps... but not Tools/msi/core/ or the like.
# Ignore core dumps... but not .../core/ subdirectories
core
!core/
@@ -158,7 +158,6 @@ Tools/unicode/data/
/coverage/
/externals/
/htmlcov/
Tools/msi/obj
Tools/ssl/amd64
Tools/ssl/win32
Tools/freeze/test/outdir
+16
View File
@@ -43,3 +43,19 @@ c-api/typeobj.html: c.Py_tp_bases
# Removed pages
library/asyncio-policy.html: (page missing)
# Removed old Windows installer docs
using/windows.html: diagnostics
using/windows.html: dry-run
using/windows.html: from-a-script
using/windows.html: from-file-associations
using/windows.html: from-the-command-line
using/windows.html: install-on-demand
using/windows.html: install-quiet-option
using/windows.html: installing-without-ui
using/windows.html: modifying-an-install
using/windows.html: python-launcher-for-windows-deprecated
using/windows.html: return-codes
using/windows.html: the-full-installer-deprecated
using/windows.html: virtual-environments
using/windows.html: windows-full
Binary file not shown.

Before

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

+9 -722
View File
@@ -59,6 +59,8 @@ packages.
.. _setting-envvars:
.. _windows-path-mod:
.. _launcher:
.. _getting-started:
.. _installation-steps:
Python install manager
======================
@@ -315,6 +317,8 @@ for new users, but should not generally be relied on rather than using the
.. _pymanager-offline:
.. _install-layout-option:
.. _installing-without-downloading:
Offline installs
----------------
@@ -378,6 +382,10 @@ again. To completely clean up all Python runtimes, run with ``--purge`` before
uninstalling the Python install manager.
.. _pymanager-config:
.. _customization:
.. _customizing-default-python-versions:
.. _customization-via-ini-files:
.. _launcher-ini:
Configuration
-------------
@@ -518,6 +526,7 @@ Dotted names should be nested inside JSON objects, for example, ``list.format``
would be specified as ``{"list": {"format": "table"}}``.
.. _pymanager-shebang:
.. _arguments-in-shebang-lines:
Shebang lines
-------------
@@ -1501,725 +1510,3 @@ releases. These files are in the :file:`PCbuild` directory.
Check :file:`PCbuild/readme.txt` for general information on the build process.
For extension modules, consult :ref:`building-on-windows`.
.. _windows-full:
The full installer (deprecated)
===============================
.. deprecated:: 3.14
This installer is deprecated since 3.14 and will not be produced for Python
3.16 or later. See :ref:`pymanager` for the modern installer.
Installation steps
------------------
Four Python |version| installers are available for download - two each for the
32-bit and 64-bit versions of the interpreter. The *web installer* is a small
initial download, and it will automatically download the required components as
necessary. The *offline installer* includes the components necessary for a
default installation and only requires an internet connection for optional
features. See :ref:`install-layout-option` for other ways to avoid downloading
during installation.
After starting the installer, one of two options may be selected:
.. image:: win_installer.png
If you select "Install Now":
* You will *not* need to be an administrator (unless a system update for the
C Runtime Library is required or you install the :ref:`launcher` for all
users)
* Python will be installed into your user directory
* The :ref:`launcher` will be installed according to the option at the bottom
of the first page
* The standard library, test suite, launcher and pip will be installed
* If selected, the install directory will be added to your :envvar:`PATH`
* Shortcuts will only be visible for the current user
Selecting "Customize installation" will allow you to select the features to
install, the installation location and other options or post-install actions.
To install debugging symbols or binaries, you will need to use this option.
To perform an all-users installation, you should select "Customize
installation". In this case:
* You may be required to provide administrative credentials or approval
* Python will be installed into the Program Files directory
* The :ref:`launcher` will be installed into the Windows directory
* Optional features may be selected during installation
* The standard library can be pre-compiled to bytecode
* If selected, the install directory will be added to the system :envvar:`PATH`
* Shortcuts are available for all users
Removing the MAX_PATH limitation
--------------------------------
Windows historically has limited path lengths to 260 characters. This meant that
paths longer than this would not resolve and errors would result.
In the latest versions of Windows, this limitation can be expanded to
approximately 32,000 characters. Your administrator will need to activate the
"Enable Win32 long paths" group policy, or set ``LongPathsEnabled`` to ``1``
in the registry key
``HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem``.
This allows the :func:`open` function, the :mod:`os` module and most other
path functionality to accept and return paths longer than 260 characters.
After changing the above option, no further configuration is required.
.. versionchanged:: 3.6
Support for long paths was enabled in Python.
.. _install-quiet-option:
Installing without UI
---------------------
All of the options available in the installer UI can also be specified from the
command line, allowing scripted installers to replicate an installation on many
machines without user interaction. These options may also be set without
suppressing the UI in order to change some of the defaults.
The following options (found by executing the installer with ``/?``) can be
passed into the installer:
+---------------------+--------------------------------------------------------+
| Name | Description |
+=====================+========================================================+
| /passive | to display progress without requiring user interaction |
+---------------------+--------------------------------------------------------+
| /quiet | to install/uninstall without displaying any UI |
+---------------------+--------------------------------------------------------+
| /simple | to prevent user customization |
+---------------------+--------------------------------------------------------+
| /uninstall | to remove Python (without confirmation) |
+---------------------+--------------------------------------------------------+
| /layout [directory] | to pre-download all components |
+---------------------+--------------------------------------------------------+
| /log [filename] | to specify log files location |
+---------------------+--------------------------------------------------------+
All other options are passed as ``name=value``, where the value is usually
``0`` to disable a feature, ``1`` to enable a feature, or a path. The full list
of available options is shown below.
+---------------------------+--------------------------------------+--------------------------+
| Name | Description | Default |
+===========================+======================================+==========================+
| InstallAllUsers | Perform a system-wide installation. | 0 |
+---------------------------+--------------------------------------+--------------------------+
| TargetDir | The installation directory | Selected based on |
| | | InstallAllUsers |
+---------------------------+--------------------------------------+--------------------------+
| DefaultAllUsersTargetDir | The default installation directory | :file:`%ProgramFiles%\\\ |
| | for all-user installs | Python X.Y` or :file:`\ |
| | | %ProgramFiles(x86)%\\\ |
| | | Python X.Y` |
+---------------------------+--------------------------------------+--------------------------+
| DefaultJustForMeTargetDir | The default install directory for | :file:`%LocalAppData%\\\ |
| | just-for-me installs | Programs\\Python\\\ |
| | | PythonXY` or |
| | | :file:`%LocalAppData%\\\ |
| | | Programs\\Python\\\ |
| | | PythonXY-32` or |
| | | :file:`%LocalAppData%\\\ |
| | | Programs\\Python\\\ |
| | | PythonXY-64` |
+---------------------------+--------------------------------------+--------------------------+
| DefaultCustomTargetDir | The default custom install directory | (empty) |
| | displayed in the UI | |
+---------------------------+--------------------------------------+--------------------------+
| AssociateFiles | Create file associations if the | 1 |
| | launcher is also installed. | |
+---------------------------+--------------------------------------+--------------------------+
| CompileAll | Compile all ``.py`` files to | 0 |
| | ``.pyc``. | |
+---------------------------+--------------------------------------+--------------------------+
| PrependPath | Prepend install and Scripts | 0 |
| | directories to :envvar:`PATH` and | |
| | add ``.PY`` to :envvar:`PATHEXT` | |
+---------------------------+--------------------------------------+--------------------------+
| AppendPath | Append install and Scripts | 0 |
| | directories to :envvar:`PATH` and | |
| | add ``.PY`` to :envvar:`PATHEXT` | |
+---------------------------+--------------------------------------+--------------------------+
| Shortcuts | Create shortcuts for the interpreter,| 1 |
| | documentation and IDLE if installed. | |
+---------------------------+--------------------------------------+--------------------------+
| Include_doc | Install Python manual | 1 |
+---------------------------+--------------------------------------+--------------------------+
| Include_debug | Install debug binaries | 0 |
+---------------------------+--------------------------------------+--------------------------+
| Include_dev | Install developer headers and | 1 |
| | libraries. Omitting this may lead to | |
| | an unusable installation. | |
+---------------------------+--------------------------------------+--------------------------+
| Include_exe | Install :file:`python.exe` and | 1 |
| | related files. Omitting this may | |
| | lead to an unusable installation. | |
+---------------------------+--------------------------------------+--------------------------+
| Include_launcher | Install :ref:`launcher`. | 1 |
+---------------------------+--------------------------------------+--------------------------+
| InstallLauncherAllUsers | Installs the launcher for all | 1 |
| | users. Also requires | |
| | ``Include_launcher`` to be set to 1 | |
+---------------------------+--------------------------------------+--------------------------+
| Include_lib | Install standard library and | 1 |
| | extension modules. Omitting this may | |
| | lead to an unusable installation. | |
+---------------------------+--------------------------------------+--------------------------+
| Include_pip | Install bundled pip and setuptools | 1 |
+---------------------------+--------------------------------------+--------------------------+
| Include_symbols | Install debugging symbols (``*.pdb``)| 0 |
+---------------------------+--------------------------------------+--------------------------+
| Include_tcltk | Install Tcl/Tk support and IDLE | 1 |
+---------------------------+--------------------------------------+--------------------------+
| Include_test | Install standard library test suite | 1 |
+---------------------------+--------------------------------------+--------------------------+
| Include_tools | Install utility scripts | 1 |
+---------------------------+--------------------------------------+--------------------------+
| LauncherOnly | Only installs the launcher. This | 0 |
| | will override most other options. | |
+---------------------------+--------------------------------------+--------------------------+
| SimpleInstall | Disable most install UI | 0 |
+---------------------------+--------------------------------------+--------------------------+
| SimpleInstallDescription | A custom message to display when the | (empty) |
| | simplified install UI is used. | |
+---------------------------+--------------------------------------+--------------------------+
For example, to silently install a default, system-wide Python installation,
you could use the following command (from an elevated command prompt)::
python-3.9.0.exe /quiet InstallAllUsers=1 PrependPath=1 Include_test=0
To allow users to easily install a personal copy of Python without the test
suite, you could provide a shortcut with the following command. This will
display a simplified initial page and disallow customization::
python-3.9.0.exe InstallAllUsers=0 Include_launcher=0 Include_test=0
SimpleInstall=1 SimpleInstallDescription="Just for me, no test suite."
(Note that omitting the launcher also omits file associations, and is only
recommended for per-user installs when there is also a system-wide installation
that included the launcher.)
The options listed above can also be provided in a file named ``unattend.xml``
alongside the executable. This file specifies a list of options and values.
When a value is provided as an attribute, it will be converted to a number if
possible. Values provided as element text are always left as strings. This
example file sets the same options as the previous example:
.. code-block:: xml
<Options>
<Option Name="InstallAllUsers" Value="no" />
<Option Name="Include_launcher" Value="0" />
<Option Name="Include_test" Value="no" />
<Option Name="SimpleInstall" Value="yes" />
<Option Name="SimpleInstallDescription">Just for me, no test suite</Option>
</Options>
.. _install-layout-option:
Installing without downloading
------------------------------
As some features of Python are not included in the initial installer download,
selecting those features may require an internet connection. To avoid this
need, all possible components may be downloaded on-demand to create a complete
*layout* that will no longer require an internet connection regardless of the
selected features. Note that this download may be bigger than required, but
where a large number of installations are going to be performed it is very
useful to have a locally cached copy.
Execute the following command from Command Prompt to download all possible
required files. Remember to substitute ``python-3.9.0.exe`` for the actual
name of your installer, and to create layouts in their own directories to
avoid collisions between files with the same name.
::
python-3.9.0.exe /layout [optional target directory]
You may also specify the ``/quiet`` option to hide the progress display.
Modifying an install
--------------------
Once Python has been installed, you can add or remove features through the
Programs and Features tool that is part of Windows. Select the Python entry and
choose "Uninstall/Change" to open the installer in maintenance mode.
"Modify" allows you to add or remove features by modifying the checkboxes -
unchanged checkboxes will not install or remove anything. Some options cannot be
changed in this mode, such as the install directory; to modify these, you will
need to remove and then reinstall Python completely.
"Repair" will verify all the files that should be installed using the current
settings and replace any that have been removed or modified.
"Uninstall" will remove Python entirely, with the exception of the
:ref:`launcher`, which has its own entry in Programs and Features.
Installing free-threaded binaries
---------------------------------
.. versionadded:: 3.13
To install pre-built binaries with free-threading enabled (see :pep:`703`), you
should select "Customize installation". The second page of options includes the
"Download free-threaded binaries" checkbox.
.. image:: win_install_freethreaded.png
Selecting this option will download and install additional binaries to the same
location as the main Python install. The main executable is called
``python3.13t.exe``, and other binaries either receive a ``t`` suffix or a full
ABI suffix. Python source files and bundled third-party dependencies are shared
with the main install.
The free-threaded version is registered as a regular Python install with the
tag ``3.13t`` (with a ``-32`` or ``-arm64`` suffix as normal for those
platforms). This allows tools to discover it, and for the :ref:`launcher` to
support ``py.exe -3.13t``. Note that the launcher will interpret ``py.exe -3``
(or a ``python3`` shebang) as "the latest 3.x install", which will prefer the
free-threaded binaries over the regular ones, while ``py.exe -3.13`` will not.
If you use the short style of option, you may prefer to not install the
free-threaded binaries at this time.
To specify the install option at the command line, use
``Include_freethreaded=1``. See :ref:`install-layout-option` for instructions on
pre-emptively downloading the additional binaries for offline install. The
options to include debug symbols and binaries also apply to the free-threaded
builds.
Free-threaded binaries are also available :ref:`on nuget.org <windows-nuget>`.
Python launcher for Windows (deprecated)
========================================
.. deprecated:: 3.14
The launcher and this documentation have been superseded by the Python
Install Manager described above. This is preserved temporarily for historical
interest.
.. versionadded:: 3.3
The Python launcher for Windows is a utility which aids in locating and
executing of different Python versions. It allows scripts (or the
command-line) to indicate a preference for a specific Python version, and
will locate and execute that version.
Unlike the :envvar:`PATH` variable, the launcher will correctly select the most
appropriate version of Python. It will prefer per-user installations over
system-wide ones, and orders by language version rather than using the most
recently installed version.
The launcher was originally specified in :pep:`397`.
Getting started
---------------
From the command-line
^^^^^^^^^^^^^^^^^^^^^
.. versionchanged:: 3.6
System-wide installations of Python 3.3 and later will put the launcher on your
:envvar:`PATH`. The launcher is compatible with all available versions of
Python, so it does not matter which version is installed. To check that the
launcher is available, execute the following command in Command Prompt::
py
You should find that the latest version of Python you have installed is
started - it can be exited as normal, and any additional command-line
arguments specified will be sent directly to Python.
If you have multiple versions of Python installed (e.g., 3.7 and |version|) you
will have noticed that Python |version| was started - to launch Python 3.7, try
the command::
py -3.7
If you want the latest version of Python 2 you have installed, try the
command::
py -2
If you see the following error, you do not have the launcher installed::
'py' is not recognized as an internal or external command,
operable program or batch file.
The command::
py --list
displays the currently installed version(s) of Python.
The ``-x.y`` argument is the short form of the ``-V:Company/Tag`` argument,
which allows selecting a specific Python runtime, including those that may have
come from somewhere other than python.org. Any runtime registered by following
:pep:`514` will be discoverable. The ``--list`` command lists all available
runtimes using the ``-V:`` format.
When using the ``-V:`` argument, specifying the Company will limit selection to
runtimes from that provider, while specifying only the Tag will select from all
providers. Note that omitting the slash implies a tag::
# Select any '3.*' tagged runtime
py -V:3
# Select any 'PythonCore' released runtime
py -V:PythonCore/
# Select PythonCore's latest Python 3 runtime
py -V:PythonCore/3
The short form of the argument (``-3``) only ever selects from core Python
releases, and not other distributions. However, the longer form (``-V:3``) will
select from any.
The Company is matched on the full string, case-insensitive. The Tag is matched
on either the full string, or a prefix, provided the next character is a dot or a
hyphen. This allows ``-V:3.1`` to match ``3.1-32``, but not ``3.10``. Tags are
sorted using numerical ordering (``3.10`` is newer than ``3.1``), but are
compared using text (``-V:3.01`` does not match ``3.1``).
Virtual environments
^^^^^^^^^^^^^^^^^^^^
.. versionadded:: 3.5
If the launcher is run with no explicit Python version specification, and a
virtual environment (created with the standard library :mod:`venv` module or
the external ``virtualenv`` tool) active, the launcher will run the virtual
environment's interpreter rather than the global one. To run the global
interpreter, either deactivate the virtual environment, or explicitly specify
the global Python version.
From a script
^^^^^^^^^^^^^
Let's create a test Python script - create a file called ``hello.py`` with the
following contents
.. code-block:: python
#! python
import sys
sys.stdout.write("hello from Python %s\n" % (sys.version,))
From the directory in which hello.py lives, execute the command::
py hello.py
You should notice the version number of your latest Python 2.x installation
is printed. Now try changing the first line to be:
.. code-block:: python
#! python3
Re-executing the command should now print the latest Python 3.x information.
As with the above command-line examples, you can specify a more explicit
version qualifier. Assuming you have Python 3.7 installed, try changing
the first line to ``#! python3.7`` and you should find the 3.7
version information printed.
Note that unlike interactive use, a bare "python" will use the latest
version of Python 2.x that you have installed. This is for backward
compatibility and for compatibility with Unix, where the command ``python``
typically refers to Python 2.
From file associations
^^^^^^^^^^^^^^^^^^^^^^
The launcher should have been associated with Python files (i.e. ``.py``,
``.pyw``, ``.pyc`` files) when it was installed. This means that
when you double-click on one of these files from Windows explorer the launcher
will be used, and therefore you can use the same facilities described above to
have the script specify the version which should be used.
The key benefit of this is that a single launcher can support multiple Python
versions at the same time depending on the contents of the first line.
Shebang lines
-------------
If the first line of a script file starts with ``#!``, it is known as a
"shebang" line. Linux and other Unix like operating systems have native
support for such lines and they are commonly used on such systems to indicate
how a script should be executed. This launcher allows the same facilities to
be used with Python scripts on Windows and the examples above demonstrate their
use.
To allow shebang lines in Python scripts to be portable between Unix and
Windows, this launcher supports a number of 'virtual' commands to specify
which interpreter to use. The supported virtual commands are:
* ``/usr/bin/env``
* ``/usr/bin/python``
* ``/usr/local/bin/python``
* ``python``
For example, if the first line of your script starts with
.. code-block:: sh
#! /usr/bin/python
The default Python or an active virtual environment will be located and used.
As many Python scripts written to work on Unix will already have this line,
you should find these scripts can be used by the launcher without modification.
If you are writing a new script on Windows which you hope will be useful on
Unix, you should use one of the shebang lines starting with ``/usr``.
Any of the above virtual commands can be suffixed with an explicit version
(either just the major version, or the major and minor version).
Furthermore the 32-bit version can be requested by adding "-32" after the
minor version. I.e. ``/usr/bin/python3.7-32`` will request usage of the
32-bit Python 3.7. If a virtual environment is active, the version will be
ignored and the environment will be used.
.. versionadded:: 3.7
Beginning with python launcher 3.7 it is possible to request 64-bit version
by the "-64" suffix. Furthermore it is possible to specify a major and
architecture without minor (i.e. ``/usr/bin/python3-64``).
.. versionchanged:: 3.11
The "-64" suffix is deprecated, and now implies "any architecture that is
not provably i386/32-bit". To request a specific environment, use the new
:samp:`-V:{TAG}` argument with the complete tag.
.. versionchanged:: 3.13
Virtual commands referencing ``python`` now prefer an active virtual
environment rather than searching :envvar:`PATH`. This handles cases where
the shebang specifies ``/usr/bin/env python3`` but :file:`python3.exe` is
not present in the active environment.
The ``/usr/bin/env`` form of shebang line has one further special property.
Before looking for installed Python interpreters, this form will search the
executable :envvar:`PATH` for a Python executable matching the name provided
as the first argument. This corresponds to the behaviour of the Unix ``env``
program, which performs a :envvar:`PATH` search.
If an executable matching the first argument after the ``env`` command cannot
be found, but the argument starts with ``python``, it will be handled as
described for the other virtual commands.
The environment variable :envvar:`!PYLAUNCHER_NO_SEARCH_PATH` may be set
(to any value) to skip this search of :envvar:`PATH`.
Shebang lines that do not match any of these patterns are looked up in the
``[commands]`` section of the launcher's :ref:`.INI file <launcher-ini>`.
This may be used to handle certain commands in a way that makes sense for your
system. The name of the command must be a single argument (no spaces in the
shebang executable), and the value substituted is the full path to the
executable (additional arguments specified in the .INI will be quoted as part
of the filename).
.. code-block:: ini
[commands]
/bin/xpython=C:\Program Files\XPython\python.exe
Any commands not found in the .INI file are treated as **Windows** executable
paths that are absolute or relative to the directory containing the script file.
This is a convenience for Windows-only scripts, such as those generated by an
installer, since the behavior is not compatible with Unix-style shells.
These paths may be quoted, and may include multiple arguments, after which the
path to the script and any additional arguments will be appended.
Arguments in shebang lines
--------------------------
The shebang lines can also specify additional options to be passed to the
Python interpreter. For example, if you have a shebang line:
.. code-block:: sh
#! /usr/bin/python -v
Then Python will be started with the ``-v`` option
Customization
-------------
.. _launcher-ini:
Customization via INI files
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Two .ini files will be searched by the launcher - ``py.ini`` in the current
user's application data directory (``%LOCALAPPDATA%`` or ``$env:LocalAppData``)
and ``py.ini`` in the same directory as the launcher. The same .ini files are
used for both the 'console' version of the launcher (i.e. py.exe) and for the
'windows' version (i.e. pyw.exe).
Customization specified in the "application directory" will have precedence over
the one next to the executable, so a user, who may not have write access to the
.ini file next to the launcher, can override commands in that global .ini file.
Customizing default Python versions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In some cases, a version qualifier can be included in a command to dictate
which version of Python will be used by the command. A version qualifier
starts with a major version number and can optionally be followed by a period
('.') and a minor version specifier. Furthermore it is possible to specify
if a 32 or 64 bit implementation shall be requested by adding "-32" or "-64".
For example, a shebang line of ``#!python`` has no version qualifier, while
``#!python3`` has a version qualifier which specifies only a major version.
If no version qualifiers are found in a command, the environment
variable :envvar:`!PY_PYTHON` can be set to specify the default version
qualifier. If it is not set, the default is "3". The variable can
specify any value that may be passed on the command line, such as "3",
"3.7", "3.7-32" or "3.7-64". (Note that the "-64" option is only
available with the launcher included with Python 3.7 or newer.)
If no minor version qualifiers are found, the environment variable
``PY_PYTHON{major}`` (where ``{major}`` is the current major version qualifier
as determined above) can be set to specify the full version. If no such option
is found, the launcher will enumerate the installed Python versions and use
the latest minor release found for the major version, which is likely,
although not guaranteed, to be the most recently installed version in that
family.
On 64-bit Windows with both 32-bit and 64-bit implementations of the same
(major.minor) Python version installed, the 64-bit version will always be
preferred. This will be true for both 32-bit and 64-bit implementations of the
launcher - a 32-bit launcher will prefer to execute a 64-bit Python installation
of the specified version if available. This is so the behavior of the launcher
can be predicted knowing only what versions are installed on the PC and
without regard to the order in which they were installed (i.e., without knowing
whether a 32 or 64-bit version of Python and corresponding launcher was
installed last). As noted above, an optional "-32" or "-64" suffix can be
used on a version specifier to change this behaviour.
Examples:
* If no relevant options are set, the commands ``python`` and
``python2`` will use the latest Python 2.x version installed and
the command ``python3`` will use the latest Python 3.x installed.
* The command ``python3.7`` will not consult any
options at all as the versions are fully specified.
* If ``PY_PYTHON=3``, the commands ``python`` and ``python3`` will both use
the latest installed Python 3 version.
* If ``PY_PYTHON=3.7-32``, the command ``python`` will use the 32-bit
implementation of 3.7 whereas the command ``python3`` will use the latest
installed Python (PY_PYTHON was not considered at all as a major
version was specified.)
* If ``PY_PYTHON=3`` and ``PY_PYTHON3=3.7``, the commands
``python`` and ``python3`` will both use specifically 3.7
In addition to environment variables, the same settings can be configured
in the .INI file used by the launcher. The section in the INI file is
called ``[defaults]`` and the key name will be the same as the
environment variables without the leading ``PY_`` prefix (and note that
the key names in the INI file are case insensitive.) The contents of
an environment variable will override things specified in the INI file.
For example:
* Setting ``PY_PYTHON=3.7`` is equivalent to the INI file containing:
.. code-block:: ini
[defaults]
python=3.7
* Setting ``PY_PYTHON=3`` and ``PY_PYTHON3=3.7`` is equivalent to the INI file
containing:
.. code-block:: ini
[defaults]
python=3
python3=3.7
Diagnostics
-----------
If an environment variable :envvar:`!PYLAUNCHER_DEBUG` is set (to any value), the
launcher will print diagnostic information to stderr (i.e. to the console).
While this information manages to be simultaneously verbose *and* terse, it
should allow you to see what versions of Python were located, why a
particular version was chosen and the exact command-line used to execute the
target Python. It is primarily intended for testing and debugging.
Dry run
-------
If an environment variable :envvar:`!PYLAUNCHER_DRYRUN` is set (to any value),
the launcher will output the command it would have run, but will not actually
launch Python. This may be useful for tools that want to use the launcher to
detect and then launch Python directly. Note that the command written to
standard output is always encoded using UTF-8, and may not render correctly in
the console.
Install on demand
-----------------
If an environment variable :envvar:`!PYLAUNCHER_ALLOW_INSTALL` is set (to any
value), and the requested Python version is not installed but is available on
the Microsoft Store, the launcher will attempt to install it. This may require
user interaction to complete, and you may need to run the command again.
An additional :envvar:`!PYLAUNCHER_ALWAYS_INSTALL` variable causes the launcher
to always try to install Python, even if it is detected. This is mainly intended
for testing (and should be used with :envvar:`!PYLAUNCHER_DRYRUN`).
Return codes
------------
The following exit codes may be returned by the Python launcher. Unfortunately,
there is no way to distinguish these from the exit code of Python itself.
The names of codes are as used in the sources, and are only for reference. There
is no way to access or resolve them apart from reading this page. Entries are
listed in alphabetical order of names.
+-------------------+-------+-----------------------------------------------+
| Name | Value | Description |
+===================+=======+===============================================+
| RC_BAD_VENV_CFG | 107 | A :file:`pyvenv.cfg` was found but is corrupt.|
+-------------------+-------+-----------------------------------------------+
| RC_CREATE_PROCESS | 101 | Failed to launch Python. |
+-------------------+-------+-----------------------------------------------+
| RC_INSTALLING | 111 | An install was started, but the command will |
| | | need to be re-run after it completes. |
+-------------------+-------+-----------------------------------------------+
| RC_INTERNAL_ERROR | 109 | Unexpected error. Please report a bug. |
+-------------------+-------+-----------------------------------------------+
| RC_NO_COMMANDLINE | 108 | Unable to obtain command line from the |
| | | operating system. |
+-------------------+-------+-----------------------------------------------+
| RC_NO_PYTHON | 103 | Unable to locate the requested version. |
+-------------------+-------+-----------------------------------------------+
| RC_NO_VENV_CFG | 106 | A :file:`pyvenv.cfg` was required but not |
| | | found. |
+-------------------+-------+-----------------------------------------------+
+1 -1
View File
@@ -522,7 +522,7 @@ Other CPython Implementation Changes
have been removed, as they can be derived from ``exc_value``.
(Contributed by Irit Katriel in :issue:`45711`.)
* A new :ref:`command line option <install-quiet-option>`, ``AppendPath``,
* A new command line option, ``AppendPath``,
has been added for the Windows installer.
It behaves similarly to ``PrependPath``,
but appends the install and scripts directories instead of prepending them.
-3
View File
@@ -310,9 +310,6 @@ Known values:
You should always use the *upcoming* tag. For example, if 3.12a6 came out
a week ago, I should put "Python 3.12a7" next to my new magic number.
Whenever PYC_MAGIC_NUMBER is changed, the ranges in the magic_values array in
PC/launcher.c must also be updated.
*/
#define PYC_MAGIC_NUMBER 3704
+1 -3
View File
@@ -307,9 +307,7 @@ With a new bytecode you must also change what is called the "magic number" for
.pyc files: bump the value of the variable `MAGIC_NUMBER` in
[`Lib/importlib/_bootstrap_external.py`](../Lib/importlib/_bootstrap_external.py).
Changing this number will lead to all .pyc files with the old `MAGIC_NUMBER`
to be recompiled by the interpreter on import. Whenever `MAGIC_NUMBER` is
changed, the ranges in the `magic_values` array in
[`PC/launcher.c`](../PC/launcher.c) may also need to be updated. Changes to
to be recompiled by the interpreter on import. Changes to
[`Lib/importlib/_bootstrap_external.py`](../Lib/importlib/_bootstrap_external.py)
will take effect only after running `make regen-importlib`.
-804
View File
@@ -1,804 +0,0 @@
import contextlib
import itertools
import os
import re
import shutil
import subprocess
import sys
import sysconfig
import tempfile
import unittest
from pathlib import Path
from test import support
if sys.platform != "win32":
raise unittest.SkipTest("test only applies to Windows")
# Get winreg after the platform check
import winreg
PY_EXE = "py.exe"
DEBUG_BUILD = False
if sys.executable.casefold().endswith("_d.exe".casefold()):
PY_EXE = "py_d.exe"
DEBUG_BUILD = True
# Registry data to create. On removal, everything beneath top-level names will
# be deleted.
TEST_DATA = {
"PythonTestSuite": {
"DisplayName": "Python Test Suite",
"SupportUrl": "https://www.python.org/",
"3.100": {
"DisplayName": "X.Y version",
"InstallPath": {
None: sys.prefix,
"ExecutablePath": "X.Y.exe",
}
},
"3.100-32": {
"DisplayName": "X.Y-32 version",
"InstallPath": {
None: sys.prefix,
"ExecutablePath": "X.Y-32.exe",
}
},
"3.100-arm64": {
"DisplayName": "X.Y-arm64 version",
"InstallPath": {
None: sys.prefix,
"ExecutablePath": "X.Y-arm64.exe",
"ExecutableArguments": "-X fake_arg_for_test",
}
},
"ignored": {
"DisplayName": "Ignored because no ExecutablePath",
"InstallPath": {
None: sys.prefix,
}
},
},
"PythonTestSuite1": {
"DisplayName": "Python Test Suite Single",
"3.100": {
"DisplayName": "Single Interpreter",
"InstallPath": {
None: sys.prefix,
"ExecutablePath": sys.executable,
}
}
},
}
TEST_PY_ENV = dict(
PY_PYTHON="PythonTestSuite/3.100",
PY_PYTHON2="PythonTestSuite/3.100-32",
PY_PYTHON3="PythonTestSuite/3.100-arm64",
)
TEST_PY_DEFAULTS = "\n".join([
"[defaults]",
*[f"{k[3:].lower()}={v}" for k, v in TEST_PY_ENV.items()],
])
TEST_PY_COMMANDS = "\n".join([
"[commands]",
"test-command=TEST_EXE.exe",
])
def quote(s):
s = str(s)
return f'"{s}"' if " " in s else s
def create_registry_data(root, data):
def _create_registry_data(root, key, value):
if isinstance(value, dict):
# For a dict, we recursively create keys
with winreg.CreateKeyEx(root, key) as hkey:
for k, v in value.items():
_create_registry_data(hkey, k, v)
elif isinstance(value, str):
# For strings, we set values. 'key' may be None in this case
winreg.SetValueEx(root, key, None, winreg.REG_SZ, value)
else:
raise TypeError("don't know how to create data for '{}'".format(value))
for k, v in data.items():
_create_registry_data(root, k, v)
def enum_keys(root):
for i in itertools.count():
try:
yield winreg.EnumKey(root, i)
except OSError as ex:
if ex.winerror == 259:
break
raise
def delete_registry_data(root, keys):
ACCESS = winreg.KEY_WRITE | winreg.KEY_ENUMERATE_SUB_KEYS
for key in list(keys):
with winreg.OpenKey(root, key, access=ACCESS) as hkey:
delete_registry_data(hkey, enum_keys(hkey))
winreg.DeleteKey(root, key)
def is_installed(tag):
key = rf"Software\Python\PythonCore\{tag}\InstallPath"
for root, flag in [
(winreg.HKEY_CURRENT_USER, 0),
(winreg.HKEY_LOCAL_MACHINE, winreg.KEY_WOW64_64KEY),
(winreg.HKEY_LOCAL_MACHINE, winreg.KEY_WOW64_32KEY),
]:
try:
winreg.CloseKey(winreg.OpenKey(root, key, access=winreg.KEY_READ | flag))
return True
except OSError:
pass
return False
class PreservePyIni:
def __init__(self, path, content):
self.path = Path(path)
self.content = content
self._preserved = None
def __enter__(self):
try:
self._preserved = self.path.read_bytes()
except FileNotFoundError:
self._preserved = None
self.path.write_text(self.content, encoding="utf-16")
def __exit__(self, *exc_info):
if self._preserved is None:
self.path.unlink()
else:
self.path.write_bytes(self._preserved)
class RunPyMixin:
py_exe = None
@classmethod
def find_py(cls):
py_exe = None
if sysconfig.is_python_build():
py_exe = Path(sys.executable).parent / PY_EXE
else:
for p in os.getenv("PATH").split(";"):
if p:
py_exe = Path(p) / PY_EXE
if py_exe.is_file():
break
else:
py_exe = None
# Test launch and check version, to exclude installs of older
# releases when running outside of a source tree
if py_exe:
try:
with subprocess.Popen(
[py_exe, "-h"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
encoding="ascii",
errors="ignore",
) as p:
p.stdin.close()
version = next(p.stdout, "\n").splitlines()[0].rpartition(" ")[2]
p.stdout.read()
p.wait(10)
if not sys.version.startswith(version):
py_exe = None
except OSError:
py_exe = None
if not py_exe:
raise unittest.SkipTest(
"cannot locate '{}' for test".format(PY_EXE)
)
return py_exe
def get_py_exe(self):
if not self.py_exe:
self.py_exe = self.find_py()
return self.py_exe
def run_py(self, args, env=None, allow_fail=False, expect_returncode=0, argv=None):
if not self.py_exe:
self.py_exe = self.find_py()
ignore = {"VIRTUAL_ENV", "PY_PYTHON", "PY_PYTHON2", "PY_PYTHON3"}
env = {
**{k.upper(): v for k, v in os.environ.items() if k.upper() not in ignore},
"PYLAUNCHER_DEBUG": "1",
"PYLAUNCHER_DRYRUN": "1",
"PYLAUNCHER_LIMIT_TO_COMPANY": "",
**{k.upper(): v for k, v in (env or {}).items()},
}
if ini_dir := getattr(self, '_ini_dir', None):
env.setdefault("_PYLAUNCHER_INIDIR", ini_dir)
if not argv:
argv = [self.py_exe, *args]
with subprocess.Popen(
argv,
env=env,
executable=self.py_exe,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
) as p:
p.stdin.close()
p.wait(10)
out = p.stdout.read().decode("utf-8", "replace")
err = p.stderr.read().decode("ascii", "replace").replace("\uFFFD", "?")
if p.returncode != expect_returncode and support.verbose and not allow_fail:
print("++ COMMAND ++")
print([self.py_exe, *args])
print("++ STDOUT ++")
print(out)
print("++ STDERR ++")
print(err)
if allow_fail and p.returncode != expect_returncode:
raise subprocess.CalledProcessError(p.returncode, [self.py_exe, *args], out, err)
else:
self.assertEqual(expect_returncode, p.returncode)
data = {
s.partition(":")[0]: s.partition(":")[2].lstrip()
for s in err.splitlines()
if not s.startswith("#") and ":" in s
}
data["stdout"] = out
data["stderr"] = err
return data
def py_ini(self, content):
ini_dir = getattr(self, '_ini_dir', None)
if not ini_dir:
local_appdata = os.environ.get("LOCALAPPDATA")
if not local_appdata:
raise unittest.SkipTest("LOCALAPPDATA environment variable is "
"missing or empty")
ini_dir = local_appdata
return PreservePyIni(Path(ini_dir) / "py.ini", content)
@contextlib.contextmanager
def script(self, content, encoding="utf-8"):
file = Path(tempfile.mktemp(dir=os.getcwd()) + ".py")
if isinstance(content, bytes):
file.write_bytes(content)
else:
file.write_text(content, encoding=encoding)
try:
yield file
finally:
file.unlink()
@contextlib.contextmanager
def fake_venv(self):
venv = Path.cwd() / "Scripts"
venv.mkdir(exist_ok=True, parents=True)
venv_exe = (venv / ("python_d.exe" if DEBUG_BUILD else "python.exe"))
venv_exe.touch()
try:
yield venv_exe, {"VIRTUAL_ENV": str(venv.parent)}
finally:
shutil.rmtree(venv)
class TestLauncher(unittest.TestCase, RunPyMixin):
@classmethod
def setUpClass(cls):
with winreg.CreateKey(winreg.HKEY_CURRENT_USER, rf"Software\Python") as key:
create_registry_data(key, TEST_DATA)
if support.verbose:
p = subprocess.check_output("reg query HKCU\\Software\\Python /s")
#print(p.decode('mbcs'))
cls._ini_dir = tempfile.mkdtemp()
cls.addClassCleanup(shutil.rmtree, cls._ini_dir, ignore_errors=True)
@classmethod
def tearDownClass(cls):
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, rf"Software\Python", access=winreg.KEY_WRITE | winreg.KEY_ENUMERATE_SUB_KEYS) as key:
delete_registry_data(key, TEST_DATA)
def test_version(self):
data = self.run_py(["-0"])
self.assertEqual(self.py_exe, Path(data["argv0"]))
self.assertEqual(sys.version.partition(" ")[0], data["version"])
def test_help_option(self):
data = self.run_py(["-h"])
self.assertEqual("True", data["SearchInfo.help"])
def test_list_option(self):
for opt, v1, v2 in [
("-0", "True", "False"),
("-0p", "False", "True"),
("--list", "True", "False"),
("--list-paths", "False", "True"),
]:
with self.subTest(opt):
data = self.run_py([opt])
self.assertEqual(v1, data["SearchInfo.list"])
self.assertEqual(v2, data["SearchInfo.listPaths"])
def test_list(self):
data = self.run_py(["--list"])
found = {}
expect = {}
for line in data["stdout"].splitlines():
m = re.match(r"\s*(.+?)\s+?(\*\s+)?(.+)$", line)
if m:
found[m.group(1)] = m.group(3)
for company in TEST_DATA:
company_data = TEST_DATA[company]
tags = [t for t in company_data if isinstance(company_data[t], dict)]
for tag in tags:
arg = f"-V:{company}/{tag}"
expect[arg] = company_data[tag]["DisplayName"]
expect.pop(f"-V:{company}/ignored", None)
actual = {k: v for k, v in found.items() if k in expect}
try:
self.assertDictEqual(expect, actual)
except:
if support.verbose:
print("*** STDOUT ***")
print(data["stdout"])
raise
def test_list_paths(self):
data = self.run_py(["--list-paths"])
found = {}
expect = {}
for line in data["stdout"].splitlines():
m = re.match(r"\s*(.+?)\s+?(\*\s+)?(.+)$", line)
if m:
found[m.group(1)] = m.group(3)
for company in TEST_DATA:
company_data = TEST_DATA[company]
tags = [t for t in company_data if isinstance(company_data[t], dict)]
for tag in tags:
arg = f"-V:{company}/{tag}"
install = company_data[tag]["InstallPath"]
try:
expect[arg] = install["ExecutablePath"]
try:
expect[arg] += " " + install["ExecutableArguments"]
except KeyError:
pass
except KeyError:
expect[arg] = str(Path(install[None]) / Path(sys.executable).name)
expect.pop(f"-V:{company}/ignored", None)
actual = {k: v for k, v in found.items() if k in expect}
try:
self.assertDictEqual(expect, actual)
except:
if support.verbose:
print("*** STDOUT ***")
print(data["stdout"])
raise
def test_filter_to_company(self):
company = "PythonTestSuite"
data = self.run_py([f"-V:{company}/"])
self.assertEqual("X.Y.exe", data["LaunchCommand"])
self.assertEqual(company, data["env.company"])
self.assertEqual("3.100", data["env.tag"])
def test_filter_to_company_with_default(self):
company = "PythonTestSuite"
data = self.run_py([f"-V:{company}/"], env=dict(PY_PYTHON="3.0"))
self.assertEqual("X.Y.exe", data["LaunchCommand"])
self.assertEqual(company, data["env.company"])
self.assertEqual("3.100", data["env.tag"])
def test_filter_to_tag(self):
company = "PythonTestSuite"
data = self.run_py(["-V:3.100"])
self.assertEqual("X.Y.exe", data["LaunchCommand"])
self.assertEqual(company, data["env.company"])
self.assertEqual("3.100", data["env.tag"])
data = self.run_py(["-V:3.100-32"])
self.assertEqual("X.Y-32.exe", data["LaunchCommand"])
self.assertEqual(company, data["env.company"])
self.assertEqual("3.100-32", data["env.tag"])
data = self.run_py(["-V:3.100-arm64"])
self.assertEqual("X.Y-arm64.exe -X fake_arg_for_test", data["LaunchCommand"])
self.assertEqual(company, data["env.company"])
self.assertEqual("3.100-arm64", data["env.tag"])
def test_filter_to_company_and_tag(self):
company = "PythonTestSuite"
data = self.run_py([f"-V:{company}/3.1"], expect_returncode=103)
data = self.run_py([f"-V:{company}/3.100"])
self.assertEqual("X.Y.exe", data["LaunchCommand"])
self.assertEqual(company, data["env.company"])
self.assertEqual("3.100", data["env.tag"])
def test_filter_with_single_install(self):
company = "PythonTestSuite1"
data = self.run_py(
["-V:Nonexistent"],
env={"PYLAUNCHER_LIMIT_TO_COMPANY": company},
expect_returncode=103,
)
def test_search_major_3(self):
try:
data = self.run_py(["-3"], allow_fail=True)
except subprocess.CalledProcessError:
raise unittest.SkipTest("requires at least one Python 3.x install")
self.assertEqual("PythonCore", data["env.company"])
self.assertStartsWith(data["env.tag"], "3.")
def test_search_major_3_32(self):
try:
data = self.run_py(["-3-32"], allow_fail=True)
except subprocess.CalledProcessError:
if not any(is_installed(f"3.{i}-32") for i in range(5, 11)):
raise unittest.SkipTest("requires at least one 32-bit Python 3.x install")
raise
self.assertEqual("PythonCore", data["env.company"])
self.assertStartsWith(data["env.tag"], "3.")
self.assertEndsWith(data["env.tag"], "-32")
def test_search_major_2(self):
try:
data = self.run_py(["-2"], allow_fail=True)
except subprocess.CalledProcessError:
if not is_installed("2.7"):
raise unittest.SkipTest("requires at least one Python 2.x install")
raise
self.assertEqual("PythonCore", data["env.company"])
self.assertStartsWith(data["env.tag"], "2.")
def test_py_default(self):
with self.py_ini(TEST_PY_DEFAULTS):
data = self.run_py(["-arg"])
self.assertEqual("PythonTestSuite", data["SearchInfo.company"])
self.assertEqual("3.100", data["SearchInfo.tag"])
self.assertEqual("X.Y.exe -arg", data["stdout"].strip())
def test_py2_default(self):
with self.py_ini(TEST_PY_DEFAULTS):
data = self.run_py(["-2", "-arg"])
self.assertEqual("PythonTestSuite", data["SearchInfo.company"])
self.assertEqual("3.100-32", data["SearchInfo.tag"])
self.assertEqual("X.Y-32.exe -arg", data["stdout"].strip())
def test_py3_default(self):
with self.py_ini(TEST_PY_DEFAULTS):
data = self.run_py(["-3", "-arg"])
self.assertEqual("PythonTestSuite", data["SearchInfo.company"])
self.assertEqual("3.100-arm64", data["SearchInfo.tag"])
self.assertEqual("X.Y-arm64.exe -X fake_arg_for_test -arg", data["stdout"].strip())
def test_py_default_env(self):
data = self.run_py(["-arg"], env=TEST_PY_ENV)
self.assertEqual("PythonTestSuite", data["SearchInfo.company"])
self.assertEqual("3.100", data["SearchInfo.tag"])
self.assertEqual("X.Y.exe -arg", data["stdout"].strip())
def test_py2_default_env(self):
data = self.run_py(["-2", "-arg"], env=TEST_PY_ENV)
self.assertEqual("PythonTestSuite", data["SearchInfo.company"])
self.assertEqual("3.100-32", data["SearchInfo.tag"])
self.assertEqual("X.Y-32.exe -arg", data["stdout"].strip())
def test_py3_default_env(self):
data = self.run_py(["-3", "-arg"], env=TEST_PY_ENV)
self.assertEqual("PythonTestSuite", data["SearchInfo.company"])
self.assertEqual("3.100-arm64", data["SearchInfo.tag"])
self.assertEqual("X.Y-arm64.exe -X fake_arg_for_test -arg", data["stdout"].strip())
def test_py_default_short_argv0(self):
with self.py_ini(TEST_PY_DEFAULTS):
for argv0 in ['"py.exe"', 'py.exe', '"py"', 'py']:
with self.subTest(argv0):
data = self.run_py(["--version"], argv=f'{argv0} --version')
self.assertEqual("PythonTestSuite", data["SearchInfo.company"])
self.assertEqual("3.100", data["SearchInfo.tag"])
self.assertEqual("X.Y.exe --version", data["stdout"].strip())
def test_py_default_in_list(self):
data = self.run_py(["-0"], env=TEST_PY_ENV)
default = None
for line in data["stdout"].splitlines():
m = re.match(r"\s*-V:(.+?)\s+?\*\s+(.+)$", line)
if m:
default = m.group(1)
break
self.assertEqual("PythonTestSuite/3.100", default)
def test_virtualenv_in_list(self):
with self.fake_venv() as (venv_exe, env):
data = self.run_py(["-0p"], env=env)
for line in data["stdout"].splitlines():
m = re.match(r"\s*\*\s+(.+)$", line)
if m:
self.assertEqual(str(venv_exe), m.group(1))
break
else:
if support.verbose:
print(data["stdout"])
print(data["stderr"])
self.fail("did not find active venv path")
data = self.run_py(["-0"], env=env)
for line in data["stdout"].splitlines():
m = re.match(r"\s*\*\s+(.+)$", line)
if m:
self.assertEqual("Active venv", m.group(1))
break
else:
self.fail("did not find active venv entry")
def test_virtualenv_with_env(self):
with self.fake_venv() as (venv_exe, env):
data1 = self.run_py([], env={**env, "PY_PYTHON": "PythonTestSuite/3"})
data2 = self.run_py(["-V:PythonTestSuite/3"], env={**env, "PY_PYTHON": "PythonTestSuite/3"})
# Compare stdout, because stderr goes via ascii
self.assertEqual(data1["stdout"].strip(), quote(venv_exe))
self.assertEqual(data1["SearchInfo.lowPriorityTag"], "True")
# Ensure passing the argument doesn't trigger the same behaviour
self.assertNotEqual(data2["stdout"].strip(), quote(venv_exe))
self.assertNotEqual(data2["SearchInfo.lowPriorityTag"], "True")
def test_py_shebang(self):
with self.py_ini(TEST_PY_DEFAULTS):
with self.script("#! /usr/bin/python -prearg") as script:
data = self.run_py([script, "-postarg"])
self.assertEqual("PythonTestSuite", data["SearchInfo.company"])
self.assertEqual("3.100", data["SearchInfo.tag"])
self.assertEqual(f"X.Y.exe -prearg {quote(script)} -postarg", data["stdout"].strip())
def test_python_shebang(self):
with self.py_ini(TEST_PY_DEFAULTS):
with self.script("#! python -prearg") as script:
data = self.run_py([script, "-postarg"])
self.assertEqual("PythonTestSuite", data["SearchInfo.company"])
self.assertEqual("3.100", data["SearchInfo.tag"])
self.assertEqual(f"X.Y.exe -prearg {quote(script)} -postarg", data["stdout"].strip())
def test_py2_shebang(self):
with self.py_ini(TEST_PY_DEFAULTS):
with self.script("#! /usr/bin/python2 -prearg") as script:
data = self.run_py([script, "-postarg"])
self.assertEqual("PythonTestSuite", data["SearchInfo.company"])
self.assertEqual("3.100-32", data["SearchInfo.tag"])
self.assertEqual(f"X.Y-32.exe -prearg {quote(script)} -postarg",
data["stdout"].strip())
def test_py3_shebang(self):
with self.py_ini(TEST_PY_DEFAULTS):
with self.script("#! /usr/bin/python3 -prearg") as script:
data = self.run_py([script, "-postarg"])
self.assertEqual("PythonTestSuite", data["SearchInfo.company"])
self.assertEqual("3.100-arm64", data["SearchInfo.tag"])
self.assertEqual(f"X.Y-arm64.exe -X fake_arg_for_test -prearg {quote(script)} -postarg",
data["stdout"].strip())
def test_py_shebang_nl(self):
with self.py_ini(TEST_PY_DEFAULTS):
with self.script("#! /usr/bin/python -prearg\n") as script:
data = self.run_py([script, "-postarg"])
self.assertEqual("PythonTestSuite", data["SearchInfo.company"])
self.assertEqual("3.100", data["SearchInfo.tag"])
self.assertEqual(f"X.Y.exe -prearg {quote(script)} -postarg",
data["stdout"].strip())
def test_py2_shebang_nl(self):
with self.py_ini(TEST_PY_DEFAULTS):
with self.script("#! /usr/bin/python2 -prearg\n") as script:
data = self.run_py([script, "-postarg"])
self.assertEqual("PythonTestSuite", data["SearchInfo.company"])
self.assertEqual("3.100-32", data["SearchInfo.tag"])
self.assertEqual(f"X.Y-32.exe -prearg {quote(script)} -postarg",
data["stdout"].strip())
def test_py3_shebang_nl(self):
with self.py_ini(TEST_PY_DEFAULTS):
with self.script("#! /usr/bin/python3 -prearg\n") as script:
data = self.run_py([script, "-postarg"])
self.assertEqual("PythonTestSuite", data["SearchInfo.company"])
self.assertEqual("3.100-arm64", data["SearchInfo.tag"])
self.assertEqual(f"X.Y-arm64.exe -X fake_arg_for_test -prearg {quote(script)} -postarg",
data["stdout"].strip())
def test_py_shebang_short_argv0(self):
with self.py_ini(TEST_PY_DEFAULTS):
with self.script("#! /usr/bin/python -prearg") as script:
# Override argv to only pass "py.exe" as the command
data = self.run_py([script, "-postarg"], argv=f'"py.exe" "{script}" -postarg')
self.assertEqual("PythonTestSuite", data["SearchInfo.company"])
self.assertEqual("3.100", data["SearchInfo.tag"])
self.assertEqual(f'X.Y.exe -prearg "{script}" -postarg', data["stdout"].strip())
def test_py_shebang_valid_bom(self):
with self.py_ini(TEST_PY_DEFAULTS):
content = "#! /usr/bin/python -prearg".encode("utf-8")
with self.script(b"\xEF\xBB\xBF" + content) as script:
data = self.run_py([script, "-postarg"])
self.assertEqual("PythonTestSuite", data["SearchInfo.company"])
self.assertEqual("3.100", data["SearchInfo.tag"])
self.assertEqual(f"X.Y.exe -prearg {quote(script)} -postarg", data["stdout"].strip())
def test_py_shebang_invalid_bom(self):
with self.py_ini(TEST_PY_DEFAULTS):
content = "#! /usr/bin/python3 -prearg".encode("utf-8")
with self.script(b"\xEF\xAA\xBF" + content) as script:
data = self.run_py([script, "-postarg"])
self.assertIn("Invalid BOM", data["stderr"])
self.assertEqual("PythonTestSuite", data["SearchInfo.company"])
self.assertEqual("3.100", data["SearchInfo.tag"])
self.assertEqual(f"X.Y.exe {quote(script)} -postarg", data["stdout"].strip())
def test_py_handle_64_in_ini(self):
with self.py_ini("\n".join(["[defaults]", "python=3.999-64"])):
# Expect this to fail, but should get oldStyleTag flipped on
data = self.run_py([], allow_fail=True, expect_returncode=103)
self.assertEqual("3.999-64", data["SearchInfo.tag"])
self.assertEqual("True", data["SearchInfo.oldStyleTag"])
def test_search_path(self):
exe = Path("arbitrary-exe-name.exe").absolute()
exe.touch()
self.addCleanup(exe.unlink)
with self.py_ini(TEST_PY_DEFAULTS):
with self.script(f"#! /usr/bin/env {exe.stem} -prearg") as script:
data = self.run_py(
[script, "-postarg"],
env={"PATH": f"{exe.parent};{os.getenv('PATH')}"},
)
self.assertEqual(f"{quote(exe)} -prearg {quote(script)} -postarg",
data["stdout"].strip())
def test_search_path_exe(self):
# Leave the .exe on the name to ensure we don't add it a second time
exe = Path("arbitrary-exe-name.exe").absolute()
exe.touch()
self.addCleanup(exe.unlink)
with self.py_ini(TEST_PY_DEFAULTS):
with self.script(f"#! /usr/bin/env {exe.name} -prearg") as script:
data = self.run_py(
[script, "-postarg"],
env={"PATH": f"{exe.parent};{os.getenv('PATH')}"},
)
self.assertEqual(f"{quote(exe)} -prearg {quote(script)} -postarg",
data["stdout"].strip())
def test_recursive_search_path(self):
stem = self.get_py_exe().stem
with self.py_ini(TEST_PY_DEFAULTS):
with self.script(f"#! /usr/bin/env {stem}") as script:
data = self.run_py(
[script],
env={"PATH": f"{self.get_py_exe().parent};{os.getenv('PATH')}"},
)
# The recursive search is ignored and we get normal "py" behavior
self.assertEqual(f"X.Y.exe {quote(script)}", data["stdout"].strip())
def test_install(self):
data = self.run_py(["-V:3.10"], env={"PYLAUNCHER_ALWAYS_INSTALL": "1"}, expect_returncode=111)
cmd = data["stdout"].strip()
# If winget is runnable, we should find it. Otherwise, we'll be trying
# to open the Store.
try:
subprocess.check_call(["winget.exe", "--version"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
except FileNotFoundError:
self.assertIn("ms-windows-store://", cmd)
else:
self.assertIn("winget.exe", cmd)
# Both command lines include the store ID
self.assertIn("9PJPW5LDXLZ5", cmd)
def test_literal_shebang_absolute(self):
with self.script("#! C:/some_random_app -witharg") as script:
data = self.run_py([script])
self.assertEqual(
f"C:\\some_random_app -witharg {quote(script)}",
data["stdout"].strip(),
)
def test_literal_shebang_relative(self):
with self.script("#! ..\\some_random_app -witharg") as script:
data = self.run_py([script])
self.assertEqual(
f"{quote(script.parent.parent / 'some_random_app')} -witharg {quote(script)}",
data["stdout"].strip(),
)
def test_literal_shebang_quoted(self):
with self.script('#! "some random app" -witharg') as script:
data = self.run_py([script])
self.assertEqual(
f"{quote(script.parent / 'some random app')} -witharg {quote(script)}",
data["stdout"].strip(),
)
with self.script('#! some" random "app -witharg') as script:
data = self.run_py([script])
self.assertEqual(
f"{quote(script.parent / 'some random app')} -witharg {quote(script)}",
data["stdout"].strip(),
)
def test_literal_shebang_quoted_escape(self):
with self.script('#! some\\" random "app -witharg') as script:
data = self.run_py([script])
self.assertEqual(
f"{quote(script.parent / 'some/ random app')} -witharg {quote(script)}",
data["stdout"].strip(),
)
def test_literal_shebang_command(self):
with self.py_ini(TEST_PY_COMMANDS):
with self.script('#! test-command arg1') as script:
data = self.run_py([script])
self.assertEqual(
f"TEST_EXE.exe arg1 {quote(script)}",
data["stdout"].strip(),
)
def test_literal_shebang_invalid_template(self):
with self.script('#! /usr/bin/not-python arg1') as script:
data = self.run_py([script])
expect = script.parent / "/usr/bin/not-python"
self.assertEqual(
f"{quote(expect)} arg1 {quote(script)}",
data["stdout"].strip(),
)
def test_shebang_command_in_venv(self):
stem = "python-that-is-not-on-path"
# First ensure that our test name doesn't exist, and the launcher does
# not match any installed env
with self.script(f'#! /usr/bin/env {stem} arg1') as script:
data = self.run_py([script], expect_returncode=103)
with self.fake_venv() as (venv_exe, env):
# Put a "normal" Python on PATH as a distraction.
# The active VIRTUAL_ENV should be preferred when the name isn't an
# exact match.
exe = Path(Path(venv_exe).name).absolute()
exe.touch()
self.addCleanup(exe.unlink)
env["PATH"] = f"{exe.parent};{os.environ['PATH']}"
with self.script(f'#! /usr/bin/env {stem} arg1') as script:
data = self.run_py([script], env=env)
self.assertEqual(data["stdout"].strip(), f"{quote(venv_exe)} arg1 {quote(script)}")
with self.script(f'#! /usr/bin/env {exe.stem} arg1') as script:
data = self.run_py([script], env=env)
self.assertEqual(data["stdout"].strip(), f"{quote(exe)} arg1 {quote(script)}")
def test_shebang_executable_extension(self):
with self.script('#! /usr/bin/env python3.99') as script:
data = self.run_py([script], expect_returncode=103)
expect = "# Search PATH for python3.99.exe"
actual = [line.strip() for line in data["stderr"].splitlines()
if line.startswith("# Search PATH")]
self.assertEqual([expect], actual)
@@ -109,15 +109,6 @@ class TestProcessChangedFiles(unittest.TestCase):
self.assertTrue(result.run_tests)
self.assertFalse(result.run_windows_tests)
def test_msi(self):
for f in (
".github/workflows/reusable-windows-msi.yml",
"Tools/msi/build.bat",
):
with self.subTest(f=f):
result = process_changed_files({Path(f)})
self.assertTrue(result.run_windows_msi)
def test_all_run(self):
for f in (
".github/workflows/some-new-workflow.yml",
@@ -0,0 +1,3 @@
Removes the legacy MSI and Nuget build scripts, the legacy ``py.exe``
launcher (now replaced by the Python install manager), and adds a
``PC/layout`` readme.
-1
View File
@@ -1 +0,0 @@
<CustomCapabilityDescriptor xmlns="http://schemas.microsoft.com/appx/2016/sccd" xmlns:s="http://schemas.microsoft.com/appx/2016/sccd"><CustomCapabilities><CustomCapability Name="Microsoft.classicAppCompat_8wekyb3d8bbwe"></CustomCapability></CustomCapabilities><AuthorizedEntities><AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.7_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity><AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity><AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity><AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity><AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity><AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity><AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity><AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.14_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity><AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.15_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity><AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.16_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity><AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.17_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity><AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.7_qbz5n2kfra8p0" CertificateSignatureHash="6045e624888e299179d5ae0ceda57c9874ff6ccf889fa14b2d50f751bfb9e2f8"></AuthorizedEntity><AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.7_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity><AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0" CertificateSignatureHash="6045e624888e299179d5ae0ceda57c9874ff6ccf889fa14b2d50f751bfb9e2f8"></AuthorizedEntity><AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity><AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0" CertificateSignatureHash="6045e624888e299179d5ae0ceda57c9874ff6ccf889fa14b2d50f751bfb9e2f8"></AuthorizedEntity><AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity><AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0" CertificateSignatureHash="6045e624888e299179d5ae0ceda57c9874ff6ccf889fa14b2d50f751bfb9e2f8"></AuthorizedEntity><AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity><AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0" CertificateSignatureHash="6045e624888e299179d5ae0ceda57c9874ff6ccf889fa14b2d50f751bfb9e2f8"></AuthorizedEntity><AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity><AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0" CertificateSignatureHash="6045e624888e299179d5ae0ceda57c9874ff6ccf889fa14b2d50f751bfb9e2f8"></AuthorizedEntity><AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity><AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundLine truncated
Binary file not shown.
-41
View File
@@ -1,41 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<CustomCapabilityDescriptor xmlns="http://schemas.microsoft.com/appx/2016/sccd" xmlns:s="http://schemas.microsoft.com/appx/2016/sccd">
<CustomCapabilities>
<CustomCapability Name="Microsoft.classicAppCompat_8wekyb3d8bbwe"></CustomCapability>
</CustomCapabilities>
<AuthorizedEntities>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.7_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.14_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.15_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.16_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.17_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.7_qbz5n2kfra8p0" CertificateSignatureHash="6045e624888e299179d5ae0ceda57c9874ff6ccf889fa14b2d50f751bfb9e2f8"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.7_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0" CertificateSignatureHash="6045e624888e299179d5ae0ceda57c9874ff6ccf889fa14b2d50f751bfb9e2f8"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0" CertificateSignatureHash="6045e624888e299179d5ae0ceda57c9874ff6ccf889fa14b2d50f751bfb9e2f8"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0" CertificateSignatureHash="6045e624888e299179d5ae0ceda57c9874ff6ccf889fa14b2d50f751bfb9e2f8"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0" CertificateSignatureHash="6045e624888e299179d5ae0ceda57c9874ff6ccf889fa14b2d50f751bfb9e2f8"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0" CertificateSignatureHash="6045e624888e299179d5ae0ceda57c9874ff6ccf889fa14b2d50f751bfb9e2f8"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0" CertificateSignatureHash="6045e624888e299179d5ae0ceda57c9874ff6ccf889fa14b2d50f751bfb9e2f8"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.14_qbz5n2kfra8p0" CertificateSignatureHash="6045e624888e299179d5ae0ceda57c9874ff6ccf889fa14b2d50f751bfb9e2f8"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.14_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.15_qbz5n2kfra8p0" CertificateSignatureHash="6045e624888e299179d5ae0ceda57c9874ff6ccf889fa14b2d50f751bfb9e2f8"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.15_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.16_qbz5n2kfra8p0" CertificateSignatureHash="6045e624888e299179d5ae0ceda57c9874ff6ccf889fa14b2d50f751bfb9e2f8"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.16_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.17_qbz5n2kfra8p0" CertificateSignatureHash="6045e624888e299179d5ae0ceda57c9874ff6ccf889fa14b2d50f751bfb9e2f8"></AuthorizedEntity>
<AuthorizedEntity AppPackageFamilyName="PythonSoftwareFoundation.Python.3.17_qbz5n2kfra8p0" CertificateSignatureHash="279cd652c4e252bfbe5217ac722205d7729ba409148cfa9e6d9e5b1cb94eaff1"></AuthorizedEntity>
</AuthorizedEntities>
<Catalog>MIIucgYJKoZIhvcNAQcCoIIuYzCCLl8CAQExDzANBglghkgBZQMEAgEFADCCARAGCSsGAQQBgjcKAaCCAQEwgf4wDAYKKwYBBAGCNwwBAQQQ293slyDTMUOmVyeQqmcNSBcNMjIwMjA0MDkwNjU2WjAOBgorBgEEAYI3DAEDBQAwgbwwKgQUdgFpbn9QXi/ly4CZFKA2Eimoq6YxEjAQBgorBgEEAYI3DAIDMQKCADCBjQQg3YHMbvV3unL0mx/RJ8ihTJd1C/SYSnMHbN0yMrWijuQxaTAQBgorBgEEAYI3DAIDMQKCADBVBgorBgEEAYI3AgEEMUcwRTAQBgorBgEEAYI3AgEZogKAADAxMA0GCWCGSAFlAwQCAQUABCDdgcxu9Xe6cvSbH9EnyKFMl3UL9JhKcwds3TIytaKO5KCCE8owggYEMIID7KADAgECAhMzAA/d9uEraWrDsxZGAAAAD932MA0GCSqGSIb3DQEBCwUAMIGLMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMQwwCgYDVQQLEwNBT0MxJzAlBgNVBAMTHk1pY3Jvc29mdCBNYXJrZXRwbGFjZSBDQSBHIDAyMjAeFw0yMjAyMDQwODU5MzZaFw0yMjAyMDcwODU5MzZaMC8xLTArBgNVBAMTJDQ2ZTIwYzY2LTUxNTEtNDNhOS05MWQ4LTMwNDY0ZGZhMDg4ZjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALaMR5Ajlp2POidTxT0N47z5sukiE9fqMuI1QimTXIfB2/gPdMsNUbVCD57ha8J1DUJQpO5nuunbk3SONwfDTdWKx9u7zWubpEmgG7hZ8LTKFlF+xhS6lS/FBSSHyXpdScWPg62BMnDysqHMH/AjLw26HNPRWK8A0vx9jsalFwLg15u4MPuKN3Bpawr/OL0B+7eh/dGO3PutAqJ4aZs2lUCIyODg0q3Tzhgi7SIvFacFWJ8Qj6+D3AfasOv8oanfpNLLPhPlxXGEK9sMKHOOb8mTU9V/ibERqEKTHkJ24Vu+BwrXq5eVedtwmHT2WWR7teaIvrUT9AiPmMhx4hIF/0MCAwEAAaOCAbowggG2MBgGA1UdJQEB/wQOMAwGCisGAQQBgjdMHAEwHQYDVR0OBBYEFB4NpkpeSLk/j691tPw97rB4XKDJMA0GA1UdEQQGMASCAlVTMB8GA1UdIwQYMBaAFPeC7EkBPjJR1eFAcP4hAMeQ72IPMF8GA1UdHwRYMFYwVKBSoFCGTmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyME1hcmtldHBsYWNlJTIwQ0ElMjBHJTIwMDIyLmNybDBsBggrBgEFBQcBAQRgMF4wXAYIKwYBBQUHMAKGUGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwTWFya2V0cGxhY2UlMjBDQSUyMEclMjAwMjIuY3J0MAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMDwGCSsGAQQBgjcVBwQvMC0GJSsGAQQBgjcVCIOS9kTqrxCDkY0wgqzgLIKinDE0g+6NOIaE7wACAWQCARcwIAYJKwYBBAGCNxUKAQH/BBAwDjAMBgorBgEEAYI3TBwBMA0GCSqGSIb3DQEBCwUAA4ICAQBAiJuIJeMS+PMrxG+kwPWT7yy7A6P8trchwtXyYep/WXu7xT2tH2ys3wuP4DYG5CY4nKekjTKraQhZGuYj4r4KrUviShe8ZWMIcK4MRduXAU81UOd/fsCq5djQ6NDN4Bzq1TxjwZKiEMEWmXaunj6XAlDSX3SgyyMb/ywmur8VVKO+xFVkOxAqCjNo1VaCv3zEvr3Y6dUwO9gYQui1bAQVQzdxRYUPEJlsFBmbNL1AnZ39r4/9K/6orxavU4qwkj4cXnhtMYKDjTIIbTBrfD4glP6mnmkcZpN0ItfEAVgU9rGpXg84hQLeP83nBs2Y8DrF3bBF9867dJCl90c5rK1DMcelmH3oUAwqZ3U+jIIj3HGyfefAQ6HPL0yiY9OYLXQZUxcZF13m92l5s7dy2C21cIh0W0iTcWPIhNn9cia4Hr7FabTC0RoQkO1bg0PKvPMnoe0AqEVmPKImNDncg538AjPy2qeUxn7+0kcuZWEdKVAPwWfzh5qvSAmYKk4XNBfN2E40GQ0ruRdvMVMFeYBLXKm4SJR6zoiBa5v7qzt1uQqZf6GD4BNFZivBp0P2B9lTubEAU6SmUsazRnEVmekIO+x7gDuXbMS8tv6mb1pbGCtIV/wRcIYNcDkHKTHMbW5xR/OmGTM3mPRxoMQtaWtxIeagZkU2nl+pElA/0h7pIjCCBtcwggS/oAMCAQICCmESRKIAAAAAAAIwDQYJKoZIhvcNAQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDExMB4XDTExMDMyODIxMDkzOVoXDTMxMDMyODIxMTkzOVowfTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEnMCUGA1UEAxMeTWljcm9zb2Z0IE1hcmtldFBsYWNlIFBDQSAyMDExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAubUaSwGYVsE3MAnPfvmozUhAB3qxBABgJRW1vDp4+tVinXxD32f7k1K89JQ6zDOgS/iDgULC+yFK1K/1Qjac/0M7P6c8v5LSjnWGlERLa/qY32j46S7SLQcit3g2jgoTTO03eUG+9yHZUTGV/FJdRYB8uXhrznJBa+Y+yGwiQKF+m6XFeBH/KORoKFx+dmMoy9EWJ/m/o9IiUj2kzm9C691+vZ/I2w0Bj93W9SPPkV2PCNHlzgfIAoeajWpHmi38Wi3xZHonkzAVBHxPsCBppOoNsWvmAfUM7eBthkSPvFruekyDCPNEYhfGqgqtqLkoBebXLZCOVybF7wTQaLvse60//3P003icRcCoQYgY4NAqrF7j80o5U7DkeXxcB0xvengsaKgiAaV1DKkRbpe98wCqr1AASvm5rAJUYMU+mXmOieV2EelY2jGrenWe9FQpNXYV1NoWBh0WKoFxttoWYAnF705bIWtSZsz08ZfK6WLX4GXNLcPBlgCzfTm1sdKYASWdBbH2haaNhPapFhQQBJHKwnVW2iXErImhuPi45W3MVTZ5D9ASshZx69cLYY6xAdIa+89Kf/uRrsGOVZfahDuDw+NI183iAyzC8z/QRt2P32LYxP0xrCdqVh+DJo2i4NoE8Uk1usCdbVRuBMBQl/AwpOTq7IMvHGElf65CqzUCAwEAAaOCAUswggFHMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBQPU8s/FmEl/mCJHdO5fOiQrbOU0TAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBDuRQFTuHqp8cx0SOJNDBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3JsMF4GCCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQCjuZmM8ZVNDgp9wHsL4RY8KJ8nLinvxFTphNGCrxaLknkYG5pmMhVlX+UB/tSiW8W13W60nggz9u5xwMx7v/1t/Tgm6g2brVyOKI5A7u6/2SIJwkJKFw953K0YIKVT28w9zl8dSJnmRnyR0G86ncWbF6CLQ6A6lBQ9o2mTGVqDr4m35WKAnc6YxUUM1y74mbzFFZr63VHsCcOp3pXWnUqAY1rb6Q6NX1b3clncKqLFm0EjKHcQ56grTbwuuB7pMdh/IFCJR01MQzQbDtpEisbOeZUi43YVAAHKqI1EO9bRwg3frCjwAbml9MmI4utMW94gWFgvrMxIX+n42RBDIjf3Ot3jkT6gt3XeTTmO9bptgblZimhERdkFRUFpVtkocJeLoGuuzP93uH/Yp032wzRH+XmMgujfZv+vnfllJqxdowoQLx55FxLLeTeYfwi/xMSjZO2gNven3U/3KeSCd1kUOFS3AOrwZ0UNOXJeW5JQC6Vfd1BavFZ6FAta1fMLu3WFvNB+FqeHUaU3ya7rmtxJnzk29DeSqXgGNmVSywBS4NajI5jJIKAA6UhNJlsg8CHYwUOKf5ej8OoQCkbadUxXygAfxCfW2YBbujtI+PoyejRFxWUjYFWO5LeTI62UMyqfOEiqugoYjNxmQZla2s4YHVuqIC34R85FQlg9pKQBsDCCBuMwggTLoAMCAQICEzMAAABLZz0Eed1JFCkAAAAAAEswDQYJKoZIhvcNAQELBQAwfTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3JvcLine truncated
-31
View File
@@ -1,31 +0,0 @@
Python Launcher for Windows Version %s
usage:
%s [launcher-args] [python-args] [script [script-args]]
Launcher arguments:
-2 : Launch the latest Python 2.x version
-3 : Launch the latest Python 3.x version
-X.Y : Launch the specified Python version
The above default to an architecture native runtime, but will select any
available. Add a "-32" to the argument to only launch 32-bit runtimes,
or add "-64" to omit 32-bit runtimes (this latter option is deprecated).
To select a specific runtime, use the -V: options.
-V:TAG : Launch a Python runtime with the specified tag
-V:COMPANY/TAG : Launch a Python runtime from the specified company and
with the specified tag
-0 --list : List the available pythons
-0p --list-paths : List with paths
If no options are given but a script is specified, the script is checked for a
shebang line. Otherwise, an active virtual environment or global default will
be selected.
See https://docs.python.org/using/windows.html#python-launcher-for-windows for
additional configuration.
The following help text is from Python:
-2047
View File
File diff suppressed because it is too large. Load diff
-2858
View File
File diff suppressed because it is too large. Load diff
+341
View File
@@ -0,0 +1,341 @@
# PC/layout script
This document provides an overview of the `PC/layout` script, which is used to
convert from a build tree to a ready-to-run directory of files. It's the
equivalent of `make install` when using the Makefile. We use it for official
binary releases, but it also supports a lot of configuration and can be used for
whatever your custom scenario should look like.
The script never builds anything. It reads files from an existing build tree
(`-b`) and the source tree (`-s`), then copies or zips them into a layout. It
does not require the Python being laid out to be runnable, and it can target a
different version from the one running the script (see [Build source
options](#build-source-options)).
## Quick start
Run the script as a directory with any Python 3 interpreter. From the
repository root:
```
python PC/layout --help
```
A useful invocation names an output directory and a preset. The build
directory is inferred from the running interpreter (`-b` overrides it), but a
`--preset-<name>` (or explicit `--include-<name>` options) is required;
otherwise the result is a bare, minimal layout that is rarely useful.
```
python PC/layout --copy dist --preset-default
```
### Output options
The script produces one or both of the following outputs. At least one is
required for the run to do anything useful.
* `--copy <dir>` copies the layout into a directory.
* `--zip <file>` writes the layout into a ZIP file.
Additional output-related options:
* `--catalog <file>` writes a `.cdf` catalog definition for the non-binary
files, used later to produce a signed catalog. Compilation and signing are
separate steps.
* `--log <file>` writes all operations to a log file.
* `-t`, `--temp <dir>` sets the temporary working directory used for generated
files (ZIP library, `._pth`, extracted pip, generated JSON). When omitted, a
temporary directory is created automatically. If `--copy` targets a Dev
Drive, an adjacent temp directory on the same drive is used for speed.
* `-v` increases verbosity. Repeat for more detail.
### Layout options
Optional components are selected with `--include-<name>` flags. Presets group
these into the configurations we ship (see [Layouts](#layouts)). For a quick
throwaway layout, `-a`/`--include-all` turns on every option (except those
noted below as not affected by `--include-all`); it is intended for debugging
rather than for producing a real distribution, since it mixes components that
are never shipped together. The main component flags are:
* `--include-stable` the stable ABI DLL (`python3.dll`).
* `--include-pip` pip, extracted from the bundled wheels in
`Lib/ensurepip/_bundled`.
* `--include-pip-user` a `pip.ini` defaulting to `--user` installs.
* `--include-tcltk` Tcl, Tk and tkinter.
* `--include-idle` IDLE. Implies `--include-tcltk`.
* `--include-tests` the test suite.
* `--include-tools` scripts from `Tools`.
* `--include-venv` venv and ensurepip, plus the venv launcher executables.
* `--include-dev` headers and `.lib` files.
* `--include-symbols` `.pdb` symbol files.
* `--include-underpth` a `python<XY>._pth` file. Not affected by
`--include-all`.
* `--include-launchers` extra launcher executables (used with
`--include-appxmanifest`).
* `--include-appxmanifest` an APPX/MSIX manifest.
* `--include-props` a `python.props` MSBuild file.
* `--include-nuspec` a `python.nuspec` NuGet spec.
* `--include-chm` the CHM documentation.
* `--include-html-doc` the HTML documentation.
* `--include-freethreaded` free-threaded binaries. Not affected by
`--include-all`.
* `--include-alias`, `--include-alias3`, `--include-alias3x` aliased
entry-point executables (`python.exe`, `python3.exe`, `python3.x.exe` and
their `w` variants).
* `--include-install-json`, `--include-install-embed-json`,
`--include-install-test-json` a PyManager `__install__.json` for the
respective distribution.
* `--include-builddetails-json` a [PEP 739](https://peps.python.org/pep-0739/)
`build-details.json`.
Layout behavior flags:
* `-d`, `--debug` lays out the debug build (files with the `_d` suffix). The
debug binaries must already have been built (for example with
`PCbuild/build.bat -d`); the script never builds them.
* `-p`, `--precompile` includes `.pyc` files (at optimization levels 0, 1 and
2) instead of, or in addition to, `.py` files. The bytecode is compiled
during layout, in-process, using the `py_compile` module of the interpreter
running the script. It does not launch the laid-out runtime and does not check
its version, so it assumes the running interpreter matches the target version;
compiling with a mismatched version produces `.pyc` files the target cannot
use.
* `-z`, `--zip-lib` puts the standard library into `python<XY>.zip` rather than
a `Lib` directory.
* `--flat-dlls` places extension modules and DLLs next to the executables
rather than in a `DLLs` directory.
* `--include-cat <file>` includes an already-built `.cat` catalog file. This
only copies the named file into the layout; it does not build or sign the
catalog and requires no external tooling. Producing the `.cat` from a `.cdf`
(see `--catalog`) is a separate step.
### Source options
These options tell the script where to read from and what it is laying out.
* `-s`, `--source <dir>` the repository root. Defaults to the repository
containing the script.
* `-b`, `--build <dir>` the build directory containing the compiled binaries.
Defaults to the directory containing the running interpreter.
* `--arch <win32|amd64|arm32|arm64>` the target architecture. When omitted, it
is inferred by reading the PE header of a binary in the build directory.
* `--doc-build <dir>` the documentation build directory. Defaults to
`<source>/Doc/build`.
The following environment variables are read when set:
* `PYTHON_HEXVERSION` / `PYTHONINCLUDE` override version detection when the
target version cannot be inferred by reading `Include/patchlevel.h` from the
source tree. Set one of these when laying out a version other than the one
running the script (see below).
* `TCL_LIBRARY` locates the Tcl library when `--include-tcltk` is set. If
unset, the script falls back to `TCL_LIBRARY.env` in the build directory.
* `PYTHON_NUSPEC_VERSION`, `PYTHON_PROPS_PLATFORM` fill in the generated
`python.nuspec` and `python.props` files. When unset, the version falls back
to the detected version number and the platform falls back to a value derived
from the target architecture.
* `APPX_DATA_PUBLISHER`, `APPX_DATA_WINVER`, `APPX_DATA_SHA256` fill in the
generated APPX manifest. When unset, they fall back to defaults: a placeholder
publisher certificate name, a `MaxVersionTested` of `10.0.22000.0`, and no
SCCD hash. These defaults are fine for local use but are not suitable for a
signed, Store-ready package.
## Layouts
This section lists the common presets, which reflect our supported
configurations. Each is selected with `--preset-<name>` and expands to a fixed
set of `--include-<name>` options. They should help you understand which to use
for your scenario, and they are useful for figuring out where to put a new file
that you've just added to CPython.
A preset can be combined with additional `--include-<name>` options to add
components on top of it; the options are cumulative.
### Development Kit (`--preset-default`)
```
python PC/layout --copy dist --preset-default
```
The development kit layout. This is the closest equivalent to a full install
and contains the interpreter, the standard library in `Lib`, extension modules
in `DLLs`, headers and import libraries (`--include-dev`), symbols, pip, tcltk,
IDLE, venv, the test suite, HTML docs, the stable ABI DLL, aliases and a
`build-details.json`.
### Python install manager (`--preset-pymanager`, `--preset-pymanager-test`)
Layouts for the [Python install manager](https://github.com/python/pymanager).
This is now the primary way upstream CPython is distributed on Windows. Both
resemble the development kit but add a PyManager `__install__.json`.
`pymanager-test` additionally includes the test suite and symbols;
`--preset-pymanager-test` is what produces the `py install PythonTest\`
packages.
### Embeddable package (`--preset-embed`)
```
python PC/layout --zip embed.zip --preset-embed
```
The embeddable package: a minimal, self-contained runtime intended to be
bundled inside another application. The standard library is placed in a ZIP
(`--zip-lib`), DLLs are flattened next to the executables (`--flat-dlls`), the
library is precompiled, and a `._pth` file (`--underpth`) is included to fix the
search path and isolate the runtime from user site directories. It omits pip,
tcltk, IDLE, the tests and development files.
`--preset-embed --include-install-embed-json` is what produces the
`py install PythonEmbed\` packages.
### NuGet package (`--preset-nuget`)
The NuGet package layout. Includes development files, pip, the stable ABI,
venv, aliases, a `build-details.json`, and the `python.props` and
`python.nuspec` files that describe the package to MSBuild and NuGet.
### APPX package (`--preset-appx`)
The APPX/MSIX package layout for the Windows Store distribution. Includes the
stable ABI, pip, tcltk, IDLE, venv, development files, launchers, aliases and an
APPX manifest. This is no longer used for upstream CPython releases.
### Windows IoT Core (`--preset-iot`)
A minimal layout for Windows IoT Core: aliases, the stable ABI and pip. This is
not used for upstream CPython releases.
## Build source options
The `-b` and `-s` options let you lay out a build that is separate from the
interpreter running the script, including a different Python version.
* `-b`/`--build` points at the build tree with the compiled binaries. It does
not need to match the interpreter running the script.
* `-s`/`--source` points at the source tree that supplies `Lib`, `Include`,
`Tools` and version information.
The target version is normally read from `Include/patchlevel.h` in the source
tree. When laying out a version that differs from the running interpreter and
the source tree is not the matching one, set `PYTHON_HEXVERSION` (a hex version
such as `0x030f00a0`) or `PYTHONINCLUDE` (a directory containing
`patchlevel.h`) so the correct DLL names, suffixes and version numbers are used.
The script validates the inferred version against `patchlevel.h` and stops with
an error if they disagree.
## Tool structure
The script is a package under `PC/layout`. `main.py` drives argument parsing,
builds the file list (`get_layout`), generates derived files
(`generate_source_files`) and copies or zips the result (`copy_files`). Support
modules live in `PC/layout/support`:
* `options.py` defines the `OPTIONS` and `PRESETS` tables and generates the
`--include-*` and `--preset-*` command-line arguments. Add new options and
presets here.
* `constants.py` derives version numbers, DLL names and related constants from
`patchlevel.h` or the version environment variables.
* `filesets.py` provides the file-matching helpers (`FileStemSet`,
`FileNameSet`, `FileSuffixSet`) and the `rglob` globbing helper used
throughout `main.py`.
* `arch.py` infers the target architecture from a binary's PE header.
* `logging.py` configures logging and tracks whether errors occurred.
* `pip.py` extracts pip from the bundled wheels and lists the pip files.
* `catalog.py` generates the `.cdf`/`.cat` catalog definitions for signing.
* `props.py` generates `python.props` (NuGet/MSBuild).
* `nuspec.py` generates `python.nuspec` (NuGet).
* `appxmanifest.py` generates APPX/MSIX manifests.
* `pymanager.py` generates the PyManager `__install__.json`.
* `builddetails.py` generates the PEP 739 `build-details.json`.
### Classifying new files
`main.py` collects files by globbing shared directories -- the build output
directory (`-b`) for binaries and the source `Lib`, `Include` and `Tools`
directories -- and then filters them. A new file added to any of these is
usually picked up with no change here: build extension modules (`*.pyd`) land in
`DLLs` (or alongside the executables under `--flat-dlls`), other build DLLs land
next to them, and files under `Lib` are mirrored into the layout's `Lib`.
Changes are only needed when a new file belongs to an optional component, so it
must be routed to the right `--include-<name>` option rather than always
copied. The routing is driven by a set of file-matching tables near the top of
`main.py` (built from the `FileStemSet`, `FileNameSet` and `FileSuffixSet`
helpers in `support/filesets.py`). To classify a new file, add its name or
pattern to the matching table.
Tables that gate files on an optional component (the file is only included when
the corresponding option is set):
* `TEST_PYDS_ONLY`, `TEST_DLLS_ONLY`, `TEST_DIRS_ONLY` -- test-only extension
modules, DLLs and `Lib` directories; gated on `--include-tests`. Extension
module names starting with `_test` are already matched; add any other
test-only build module here (see also the note in `PCbuild/readme.txt`).
* `TCLTK_PYDS_ONLY`, `TCLTK_DLLS_ONLY`, `TCLTK_DIRS_ONLY`, `TCLTK_FILES_ONLY` --
Tcl/Tk/tkinter extension modules (`_tkinter`), DLLs (`tcl*`, `tk*`, `zlib1`),
`Lib` directories (`tkinter`, `turtledemo`) and files (`turtle.py`); gated on
`--include-tcltk`.
* `IDLE_DIRS_ONLY` -- IDLE's `Lib` directory (`idlelib`); gated on
`--include-idle`.
* `VENV_DIRS_ONLY` -- `venv` and `ensurepip` `Lib` directories; gated on
`--include-venv`.
Tables that exclude files outright:
* `EXCLUDE_FROM_DLLS` -- build DLLs that are handled elsewhere and must not be
copied by the generic DLL glob (`python*`, `pyshellext`, `vcruntime*`).
* `EXCLUDE_FROM_LIB` -- never copied into `Lib` (`*.pyc`, `__pycache__`,
`*.pickle`).
* `EXCLUDE_FROM_COMPILE` -- `Lib` files that must not be precompiled
(`badsyntax_*`, `bad_*`).
* `EXCLUDE_FROM_CATALOG` -- suffixes omitted from the signing catalog because
they are signed separately (`.exe`, `.pyd`, `.dll`).
Special cases in the debug and binary handling:
* `REQUIRED_DLLS` (`libcrypto*`, `libssl*`, `libffi*`) -- always copied from the
build directory even for a release layout. Most build DLLs are filtered by
their `_d` suffix to match the debug or release build being laid out; these
dependencies do not follow that naming and would otherwise be dropped, so they
are matched here to force inclusion. Add a new external dependency DLL here if
it does not use the `_d` debug-suffix convention.
When deciding where a new file goes, match it to the component it belongs to and
add it to the corresponding table. If it belongs in every layout and follows the
normal conventions, no change is needed.
## Contributing guidelines
Contributions are welcome. The script supports a broad range of scenarios, and
extending it for a new one is encouraged. Because the same code produces the
official releases across every supported version and architecture, additions
have to respect a few constraints so that existing configurations keep working.
The script runs in an unusual context, and new code must hold to the following
assumptions:
* Do not assume the Python being laid out can be launched. The script must run
correctly using only the interpreter running it, which may differ from the
target.
* Do not assume the layout version matches the version running the script.
Derive version-dependent behavior from the detected version rather than from
`sys.version` of the running interpreter. (Precompilation with `--precompile`
is the one deliberate exception, and it assumes a matching interpreter.)
* The script may be used to lay out an older version, so behavior changes have
to be preserved, either behind an option or gated on a version check, rather
than replaced outright.
* The script never builds anything. Everything it emits must already exist in
the build or source tree.
When adding features, keep the surface area aligned with upstream:
* New `--include-<name>` options for further customization are fine.
* Do not add presets beyond those used by upstream. Presets describe the
configurations we ship, so a new one implies a new supported release
artifact.
* Route new files through the classification tables (see [Classifying new
files](#classifying-new-files)) rather than adding one-off special cases.
+2
View File
@@ -151,6 +151,8 @@ RESOURCES_XML_TEMPLATE = r"""<?xml version="1.0" encoding="UTF-8" standalone="ye
</resources>"""
# This file is no longer included in our repo, but we keep the logic here for
# building with older releases. We always .is_file() before using it.
SCCD_FILENAME = "PC/classicAppCompat.sccd"
SPECIAL_LOOKUP = object()
-67
View File
@@ -1,67 +0,0 @@
#include <windows.h>
#include "python_ver_rc.h"
#ifndef RT_MANIFEST
// bpo-45220: Cannot reliably #include RT_MANIFEST from
// anywhere, so we hardcode it
#define RT_MANIFEST 24
#endif
// Include the manifest file that indicates we support all
// current versions of Windows.
1 RT_MANIFEST "python.manifest"
#if defined(PY_ICON)
1 ICON DISCARDABLE "icons\python.ico"
#elif defined(PYW_ICON)
1 ICON DISCARDABLE "icons\pythonw.ico"
#else
1 ICON DISCARDABLE "icons\launcher.ico"
2 ICON DISCARDABLE "icons\py.ico"
3 ICON DISCARDABLE "icons\pyc.ico"
4 ICON DISCARDABLE "icons\pyd.ico"
5 ICON DISCARDABLE "icons\python.ico"
6 ICON DISCARDABLE "icons\pythonw.ico"
7 ICON DISCARDABLE "icons\setup.ico"
#endif
1 USAGE "launcher-usage.txt"
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION PYVERSION64
PRODUCTVERSION PYVERSION64
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS VS_FF_DEBUG
#else
FILEFLAGS 0x0L
#endif
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "000004b0"
BEGIN
VALUE "CompanyName", PYTHON_COMPANY "\0"
VALUE "FileDescription", "Python\0"
VALUE "FileVersion", PYTHON_VERSION
VALUE "InternalName", "Python Launcher\0"
VALUE "LegalCopyright", PYTHON_COPYRIGHT "\0"
VALUE "OriginalFilename", "py" PYTHON_DEBUG_EXT ".exe\0"
VALUE "ProductName", "Python\0"
VALUE "ProductVersion", PYTHON_VERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0, 1200
END
END
-603
View File
@@ -1,603 +0,0 @@
// Support back to Vista
#define _WIN32_WINNT _WIN32_WINNT_VISTA
#include <sdkddkver.h>
// Use WRL to define a classic COM class
#define __WRL_CLASSIC_COM__
#include <wrl.h>
#include <windows.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <olectl.h>
#include <strsafe.h>
#define DDWM_UPDATEWINDOW (WM_USER+3)
static HINSTANCE hModule;
static CLIPFORMAT cfDropDescription;
static CLIPFORMAT cfDragWindow;
#define CLASS_GUID "{BEA218D2-6950-497B-9434-61683EC065FE}"
static const LPCWSTR CLASS_SUBKEY = L"Software\\Classes\\CLSID\\" CLASS_GUID;
static const LPCWSTR DRAG_MESSAGE = L"Open with %1";
using namespace Microsoft::WRL;
HRESULT FilenameListCchLengthA(LPCSTR pszSource, size_t cchMax, size_t *pcchLength, size_t *pcchCount) {
HRESULT hr = S_OK;
size_t count = 0;
size_t length = 0;
while (pszSource && pszSource[0]) {
size_t oneLength;
hr = StringCchLengthA(pszSource, cchMax - length, &oneLength);
if (FAILED(hr)) {
return hr;
}
count += 1;
length += oneLength + (strchr(pszSource, ' ') ? 3 : 1);
pszSource = &pszSource[oneLength + 1];
}
*pcchCount = count;
*pcchLength = length;
return hr;
}
HRESULT FilenameListCchLengthW(LPCWSTR pszSource, size_t cchMax, size_t *pcchLength, size_t *pcchCount) {
HRESULT hr = S_OK;
size_t count = 0;
size_t length = 0;
while (pszSource && pszSource[0]) {
size_t oneLength;
hr = StringCchLengthW(pszSource, cchMax - length, &oneLength);
if (FAILED(hr)) {
return hr;
}
count += 1;
length += oneLength + (wcschr(pszSource, ' ') ? 3 : 1);
pszSource = &pszSource[oneLength + 1];
}
*pcchCount = count;
*pcchLength = length;
return hr;
}
HRESULT FilenameListCchCopyA(STRSAFE_LPSTR pszDest, size_t cchDest, LPCSTR pszSource, LPCSTR pszSeparator) {
HRESULT hr = S_OK;
while (pszSource[0]) {
STRSAFE_LPSTR newDest;
hr = StringCchCopyExA(pszDest, cchDest, pszSource, &newDest, &cchDest, 0);
if (FAILED(hr)) {
return hr;
}
pszSource += (newDest - pszDest) + 1;
pszDest = PathQuoteSpacesA(pszDest) ? newDest + 2 : newDest;
if (pszSource[0]) {
hr = StringCchCopyExA(pszDest, cchDest, pszSeparator, &newDest, &cchDest, 0);
if (FAILED(hr)) {
return hr;
}
pszDest = newDest;
}
}
return hr;
}
HRESULT FilenameListCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, LPCWSTR pszSource, LPCWSTR pszSeparator) {
HRESULT hr = S_OK;
while (pszSource[0]) {
STRSAFE_LPWSTR newDest;
hr = StringCchCopyExW(pszDest, cchDest, pszSource, &newDest, &cchDest, 0);
if (FAILED(hr)) {
return hr;
}
pszSource += (newDest - pszDest) + 1;
pszDest = PathQuoteSpacesW(pszDest) ? newDest + 2 : newDest;
if (pszSource[0]) {
hr = StringCchCopyExW(pszDest, cchDest, pszSeparator, &newDest, &cchDest, 0);
if (FAILED(hr)) {
return hr;
}
pszDest = newDest;
}
}
return hr;
}
class DECLSPEC_UUID(CLASS_GUID) PyShellExt : public RuntimeClass<
RuntimeClassFlags<ClassicCom>,
IDropTarget,
IPersistFile
>
{
LPOLESTR target, target_dir;
DWORD target_mode;
IDataObject *data_obj;
public:
PyShellExt() : target(NULL), target_dir(NULL), target_mode(0), data_obj(NULL) {
OutputDebugString(L"PyShellExt::PyShellExt");
}
~PyShellExt() {
if (target) {
CoTaskMemFree(target);
}
if (target_dir) {
CoTaskMemFree(target_dir);
}
if (data_obj) {
data_obj->Release();
}
}
private:
HRESULT UpdateDropDescription(IDataObject *pDataObj) {
STGMEDIUM medium;
FORMATETC fmt = {
cfDropDescription,
NULL,
DVASPECT_CONTENT,
-1,
TYMED_HGLOBAL
};
auto hr = pDataObj->GetData(&fmt, &medium);
if (FAILED(hr)) {
OutputDebugString(L"PyShellExt::UpdateDropDescription - failed to get DROPDESCRIPTION format");
return hr;
}
if (!medium.hGlobal) {
OutputDebugString(L"PyShellExt::UpdateDropDescription - DROPDESCRIPTION format had NULL hGlobal");
ReleaseStgMedium(&medium);
return E_FAIL;
}
auto dd = (DROPDESCRIPTION*)GlobalLock(medium.hGlobal);
if (!dd) {
OutputDebugString(L"PyShellExt::UpdateDropDescription - failed to lock DROPDESCRIPTION hGlobal");
ReleaseStgMedium(&medium);
return E_FAIL;
}
StringCchCopy(dd->szMessage, sizeof(dd->szMessage) / sizeof(dd->szMessage[0]), DRAG_MESSAGE);
StringCchCopy(dd->szInsert, sizeof(dd->szInsert) / sizeof(dd->szInsert[0]), PathFindFileNameW(target));
dd->type = DROPIMAGE_MOVE;
GlobalUnlock(medium.hGlobal);
ReleaseStgMedium(&medium);
return S_OK;
}
HRESULT GetDragWindow(IDataObject *pDataObj, HWND *phWnd) {
HRESULT hr;
HWND *pMem;
STGMEDIUM medium;
FORMATETC fmt = {
cfDragWindow,
NULL,
DVASPECT_CONTENT,
-1,
TYMED_HGLOBAL
};
hr = pDataObj->GetData(&fmt, &medium);
if (FAILED(hr)) {
OutputDebugString(L"PyShellExt::GetDragWindow - failed to get DragWindow format");
return hr;
}
if (!medium.hGlobal) {
OutputDebugString(L"PyShellExt::GetDragWindow - DragWindow format had NULL hGlobal");
ReleaseStgMedium(&medium);
return E_FAIL;
}
pMem = (HWND*)GlobalLock(medium.hGlobal);
if (!pMem) {
OutputDebugString(L"PyShellExt::GetDragWindow - failed to lock DragWindow hGlobal");
ReleaseStgMedium(&medium);
return E_FAIL;
}
*phWnd = *pMem;
GlobalUnlock(medium.hGlobal);
ReleaseStgMedium(&medium);
return S_OK;
}
HRESULT GetArguments(IDataObject *pDataObj, LPCWSTR *pArguments) {
HRESULT hr;
DROPFILES *pdropfiles;
STGMEDIUM medium;
FORMATETC fmt = {
CF_HDROP,
NULL,
DVASPECT_CONTENT,
-1,
TYMED_HGLOBAL
};
hr = pDataObj->GetData(&fmt, &medium);
if (FAILED(hr)) {
OutputDebugString(L"PyShellExt::GetArguments - failed to get CF_HDROP format");
return hr;
}
if (!medium.hGlobal) {
OutputDebugString(L"PyShellExt::GetArguments - CF_HDROP format had NULL hGlobal");
ReleaseStgMedium(&medium);
return E_FAIL;
}
pdropfiles = (DROPFILES*)GlobalLock(medium.hGlobal);
if (!pdropfiles) {
OutputDebugString(L"PyShellExt::GetArguments - failed to lock CF_HDROP hGlobal");
ReleaseStgMedium(&medium);
return E_FAIL;
}
if (pdropfiles->fWide) {
LPCWSTR files = (LPCWSTR)((char*)pdropfiles + pdropfiles->pFiles);
size_t len, count;
hr = FilenameListCchLengthW(files, 32767, &len, &count);
if (SUCCEEDED(hr)) {
LPWSTR args = (LPWSTR)CoTaskMemAlloc(sizeof(WCHAR) * (len + 1));
if (args) {
hr = FilenameListCchCopyW(args, 32767, files, L" ");
if (SUCCEEDED(hr)) {
*pArguments = args;
} else {
CoTaskMemFree(args);
}
} else {
hr = E_OUTOFMEMORY;
}
}
} else {
LPCSTR files = (LPCSTR)((char*)pdropfiles + pdropfiles->pFiles);
size_t len, count;
hr = FilenameListCchLengthA(files, 32767, &len, &count);
if (SUCCEEDED(hr)) {
LPSTR temp = (LPSTR)CoTaskMemAlloc(sizeof(CHAR) * (len + 1));
if (temp) {
hr = FilenameListCchCopyA(temp, 32767, files, " ");
if (SUCCEEDED(hr)) {
int wlen = MultiByteToWideChar(CP_ACP, 0, temp, (int)len, NULL, 0);
if (wlen) {
LPWSTR args = (LPWSTR)CoTaskMemAlloc(sizeof(WCHAR) * (wlen + 1));
if (MultiByteToWideChar(CP_ACP, 0, temp, (int)len, args, wlen + 1)) {
*pArguments = args;
} else {
OutputDebugString(L"PyShellExt::GetArguments - failed to convert multi-byte to wide-char path");
CoTaskMemFree(args);
hr = E_FAIL;
}
} else {
OutputDebugString(L"PyShellExt::GetArguments - failed to get length of wide-char path");
hr = E_FAIL;
}
}
CoTaskMemFree(temp);
} else {
hr = E_OUTOFMEMORY;
}
}
}
GlobalUnlock(medium.hGlobal);
ReleaseStgMedium(&medium);
return hr;
}
HRESULT NotifyDragWindow(HWND hwnd) {
LRESULT res;
if (!hwnd) {
return S_FALSE;
}
res = SendMessage(hwnd, DDWM_UPDATEWINDOW, 0, NULL);
if (res) {
OutputDebugString(L"PyShellExt::NotifyDragWindow - failed to post DDWM_UPDATEWINDOW");
return E_FAIL;
}
return S_OK;
}
public:
// IDropTarget implementation
STDMETHODIMP DragEnter(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) {
HWND hwnd;
OutputDebugString(L"PyShellExt::DragEnter");
pDataObj->AddRef();
data_obj = pDataObj;
*pdwEffect = DROPEFFECT_MOVE;
if (FAILED(UpdateDropDescription(data_obj))) {
OutputDebugString(L"PyShellExt::DragEnter - failed to update drop description");
}
if (FAILED(GetDragWindow(data_obj, &hwnd))) {
OutputDebugString(L"PyShellExt::DragEnter - failed to get drag window");
}
if (FAILED(NotifyDragWindow(hwnd))) {
OutputDebugString(L"PyShellExt::DragEnter - failed to notify drag window");
}
return S_OK;
}
STDMETHODIMP DragLeave() {
return S_OK;
}
STDMETHODIMP DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) {
return S_OK;
}
STDMETHODIMP Drop(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) {
LPCWSTR args;
OutputDebugString(L"PyShellExt::Drop");
*pdwEffect = DROPEFFECT_NONE;
if (pDataObj != data_obj) {
OutputDebugString(L"PyShellExt::Drop - unexpected data object");
return E_FAIL;
}
data_obj->Release();
data_obj = NULL;
if (SUCCEEDED(GetArguments(pDataObj, &args))) {
OutputDebugString(args);
ShellExecute(NULL, NULL, target, args, target_dir, SW_NORMAL);
CoTaskMemFree((LPVOID)args);
} else {
OutputDebugString(L"PyShellExt::Drop - failed to get launch arguments");
}
return S_OK;
}
// IPersistFile implementation
STDMETHODIMP GetCurFile(LPOLESTR *ppszFileName) {
HRESULT hr;
size_t len;
if (!ppszFileName) {
return E_POINTER;
}
hr = StringCchLength(target, STRSAFE_MAX_CCH - 1, &len);
if (FAILED(hr)) {
return E_FAIL;
}
*ppszFileName = (LPOLESTR)CoTaskMemAlloc(sizeof(WCHAR) * (len + 1));
if (!*ppszFileName) {
return E_OUTOFMEMORY;
}
hr = StringCchCopy(*ppszFileName, len + 1, target);
if (FAILED(hr)) {
CoTaskMemFree(*ppszFileName);
*ppszFileName = NULL;
return E_FAIL;
}
return S_OK;
}
STDMETHODIMP IsDirty() {
return S_FALSE;
}
STDMETHODIMP Load(LPCOLESTR pszFileName, DWORD dwMode) {
HRESULT hr;
size_t len;
OutputDebugString(L"PyShellExt::Load");
OutputDebugString(pszFileName);
hr = StringCchLength(pszFileName, STRSAFE_MAX_CCH - 1, &len);
if (FAILED(hr)) {
OutputDebugString(L"PyShellExt::Load - failed to get string length");
return hr;
}
if (target) {
CoTaskMemFree(target);
}
if (target_dir) {
CoTaskMemFree(target_dir);
}
target = (LPOLESTR)CoTaskMemAlloc(sizeof(WCHAR) * (len + 1));
if (!target) {
OutputDebugString(L"PyShellExt::Load - E_OUTOFMEMORY");
return E_OUTOFMEMORY;
}
target_dir = (LPOLESTR)CoTaskMemAlloc(sizeof(WCHAR) * (len + 1));
if (!target_dir) {
OutputDebugString(L"PyShellExt::Load - E_OUTOFMEMORY");
return E_OUTOFMEMORY;
}
hr = StringCchCopy(target, len + 1, pszFileName);
if (FAILED(hr)) {
OutputDebugString(L"PyShellExt::Load - failed to copy string");
return hr;
}
hr = StringCchCopy(target_dir, len + 1, pszFileName);
if (FAILED(hr)) {
OutputDebugString(L"PyShellExt::Load - failed to copy string");
return hr;
}
if (!PathRemoveFileSpecW(target_dir)) {
OutputDebugStringW(L"PyShellExt::Load - failed to remove filespec from target");
return E_FAIL;
}
OutputDebugString(target);
target_mode = dwMode;
OutputDebugString(L"PyShellExt::Load - S_OK");
return S_OK;
}
STDMETHODIMP Save(LPCOLESTR pszFileName, BOOL fRemember) {
return E_NOTIMPL;
}
STDMETHODIMP SaveCompleted(LPCOLESTR pszFileName) {
return E_NOTIMPL;
}
STDMETHODIMP GetClassID(CLSID *pClassID) {
*pClassID = __uuidof(PyShellExt);
return S_OK;
}
};
CoCreatableClass(PyShellExt);
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, _COM_Outptr_ void** ppv) {
return Module<InProc>::GetModule().GetClassObject(rclsid, riid, ppv);
}
STDAPI DllCanUnloadNow() {
return Module<InProc>::GetModule().Terminate() ? S_OK : S_FALSE;
}
STDAPI DllRegisterServer() {
LONG res;
LPSECURITY_ATTRIBUTES psecattr = NULL;
HKEY key, ipsKey;
WCHAR modname[MAX_PATH];
DWORD modname_len;
OutputDebugString(L"PyShellExt::DllRegisterServer");
if (!hModule) {
OutputDebugString(L"PyShellExt::DllRegisterServer - module handle was not set");
return SELFREG_E_CLASS;
}
modname_len = GetModuleFileName(hModule, modname, MAX_PATH);
if (modname_len == 0 ||
(modname_len == MAX_PATH && GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
OutputDebugString(L"PyShellExt::DllRegisterServer - failed to get module file name");
return SELFREG_E_CLASS;
}
DWORD disp;
res = RegCreateKeyEx(HKEY_LOCAL_MACHINE, CLASS_SUBKEY, 0, NULL, 0,
KEY_ALL_ACCESS, psecattr, &key, &disp);
if (res == ERROR_ACCESS_DENIED) {
OutputDebugString(L"PyShellExt::DllRegisterServer - failed to write per-machine registration. Attempting per-user instead.");
res = RegCreateKeyEx(HKEY_CURRENT_USER, CLASS_SUBKEY, 0, NULL, 0,
KEY_ALL_ACCESS, psecattr, &key, &disp);
}
if (res != ERROR_SUCCESS) {
OutputDebugString(L"PyShellExt::DllRegisterServer - failed to create class key");
return SELFREG_E_CLASS;
}
res = RegCreateKeyEx(key, L"InProcServer32", 0, NULL, 0,
KEY_ALL_ACCESS, psecattr, &ipsKey, NULL);
if (res != ERROR_SUCCESS) {
RegCloseKey(key);
OutputDebugString(L"PyShellExt::DllRegisterServer - failed to create InProcServer32 key");
return SELFREG_E_CLASS;
}
res = RegSetValueEx(ipsKey, NULL, 0,
REG_SZ, (LPBYTE)modname, modname_len * sizeof(modname[0]));
if (res != ERROR_SUCCESS) {
RegCloseKey(ipsKey);
RegCloseKey(key);
OutputDebugString(L"PyShellExt::DllRegisterServer - failed to set server path");
return SELFREG_E_CLASS;
}
res = RegSetValueEx(ipsKey, L"ThreadingModel", 0,
REG_SZ, (LPBYTE)(L"Apartment"), sizeof(L"Apartment"));
RegCloseKey(ipsKey);
RegCloseKey(key);
if (res != ERROR_SUCCESS) {
OutputDebugString(L"PyShellExt::DllRegisterServer - failed to set threading model");
return SELFREG_E_CLASS;
}
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
OutputDebugString(L"PyShellExt::DllRegisterServer - S_OK");
return S_OK;
}
STDAPI DllUnregisterServer() {
LONG res_lm, res_cu;
res_lm = RegDeleteTree(HKEY_LOCAL_MACHINE, CLASS_SUBKEY);
if (res_lm != ERROR_SUCCESS && res_lm != ERROR_FILE_NOT_FOUND) {
OutputDebugString(L"PyShellExt::DllUnregisterServer - failed to delete per-machine registration");
return SELFREG_E_CLASS;
}
res_cu = RegDeleteTree(HKEY_CURRENT_USER, CLASS_SUBKEY);
if (res_cu != ERROR_SUCCESS && res_cu != ERROR_FILE_NOT_FOUND) {
OutputDebugString(L"PyShellExt::DllUnregisterServer - failed to delete per-user registration");
return SELFREG_E_CLASS;
}
if (res_lm == ERROR_FILE_NOT_FOUND && res_cu == ERROR_FILE_NOT_FOUND) {
OutputDebugString(L"PyShellExt::DllUnregisterServer - extension was not registered");
return SELFREG_E_CLASS;
}
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
OutputDebugString(L"PyShellExt::DllUnregisterServer - S_OK");
return S_OK;
}
STDAPI_(BOOL) DllMain(_In_opt_ HINSTANCE hinst, DWORD reason, _In_opt_ void*) {
if (reason == DLL_PROCESS_ATTACH) {
hModule = hinst;
cfDropDescription = RegisterClipboardFormat(CFSTR_DROPDESCRIPTION);
if (!cfDropDescription) {
OutputDebugString(L"PyShellExt::DllMain - failed to get CFSTR_DROPDESCRIPTION format");
}
cfDragWindow = RegisterClipboardFormat(L"DragWindow");
if (!cfDragWindow) {
OutputDebugString(L"PyShellExt::DllMain - failed to get DragWindow format");
}
DisableThreadLibraryCalls(hinst);
}
return TRUE;
}
-5
View File
@@ -1,5 +0,0 @@
EXPORTS
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE
-51
View File
@@ -1,51 +0,0 @@
#include <windows.h>
#include "python_ver_rc.h"
#ifndef RT_MANIFEST
// bpo-45220: Cannot reliably #include RT_MANIFEST from
// anywhere, so we hardcode it
#define RT_MANIFEST 24
#endif
// Include the manifest file that indicates we support all
// current versions of Windows.
1 RT_MANIFEST "python.manifest"
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION PYVERSION64
PRODUCTVERSION PYVERSION64
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS VS_FF_DEBUG
#else
FILEFLAGS 0x0L
#endif
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "000004b0"
BEGIN
VALUE "CompanyName", PYTHON_COMPANY "\0"
VALUE "FileDescription", "Python\0"
VALUE "FileVersion", PYTHON_VERSION
VALUE "InternalName", "Python Launcher Shell Extension\0"
VALUE "LegalCopyright", PYTHON_COPYRIGHT "\0"
VALUE "OriginalFilename", "pyshellext" PYTHON_DEBUG_EXT ".dll\0"
VALUE "ProductName", "Python\0"
VALUE "ProductVersion", PYTHON_VERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0, 1200
END
END
-156
View File
@@ -1,156 +0,0 @@
# Overview
NOTE: This file requires more content.
Since Python 3.7.2, releases have been made through the Microsoft Store
to allow easy installation on Windows 10.0.17763.0 and later.
# Building
To build the store package, the PC/layout script should be used.
Execute the directory with the build of Python to package, and pass
"-h" for full command-line options.
To sideload test builds, you will need a local certificate.
Instructions are available at
https://docs.microsoft.com/windows/uwp/packaging/create-certificate-package-signing.
After exporting your certificate, you will need the subject name and
SHA256 hash. The `certutil -dump <cert file>` command will display this
information.
To build for sideloading, use these commands in PowerShell:
```
$env:APPX_DATA_PUBLISHER=<your certificate subject name>
$env:APPX_DATA_SHA256=<your certificate SHA256>
$env:SigningCertificateFile=<your certificate file>
python PC/layout --copy <layout directory> --include-appxmanifest
Tools/msi/make_appx.ps1 <layout directory> python.msix -sign
Add-AppxPackage python.msix
```
(Note that only the last command requires PowerShell, and the others
can be used from Command Prompt. You can also double-click to install
the final package.)
To build for publishing to the Store, use these commands:
```
$env:APPX_DATA_PUBLISHER = $null
$env:APPX_DATA_SHA256 = $null
python PC/layout --copy <layout directory> --preset-appxmanifest --precompile
Tools/msi/make_appx.ps1 <layout directory> python.msix
```
Note that this package cannot be installed locally. It may only be
added to a submission for the store.
# Submission Metadata
This file contains the text that we use to fill out the store listing
for the Microsoft Store. It needs to be entered manually when creating
a new submission via the dashboard at
https://partner.microsoft.com/dashboard.
We keep it here for convenience and to allow it to be updated via pull
requests.
When submitting a new app, the HeadlessAppBypass waiver will be needed.
To request this, send an email to PartnerOps@microsoft.com with the app
ID (12 character token available from the dashboard). The waiver needs
to be applied *before* uploading the package (as of November 2019).
Ensure that the new app is named "Python.3.X", where X is the minor
version of the release. If the name provided initially does not match
the name used when building the package, the upload will fail. The
display name shown to users can be set later.
## Title
Python 3.9
## Short Title
Python
## Description
Python is an easy to learn, powerful programming language. It has efficient high-level data structures and a simple but effective approach to object-oriented programming. Python’s elegant syntax and dynamic typing, together with its interpreted nature, make it an ideal language for scripting and rapid application development in many areas on most platforms.
The Python interpreter and the extensive standard library are freely available in source or binary form for all major platforms from the Python web site, https://www.python.org/, and may be freely distributed. The same site also contains distributions of and pointers to many free third party Python modules, programs and tools, and additional documentation.
The Python interpreter is easily extended with new functions and data types implemented in C or C++ (or other languages callable from C). Python is also suitable as an extension language for customizable applications.
## ShortDescription
The Python 3.9 interpreter and runtime.
## Copyright Trademark Information
(c) Python Software Foundation
## Additional License Terms
Visit https://docs.python.org/3.9/license.html for latest license terms.
PSF LICENSE AGREEMENT FOR PYTHON 3.9
1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and
the Individual or Organization ("Licensee") accessing and otherwise using Python
3.9 software in source or binary form and its associated documentation.
2. Subject to the terms and conditions of this License Agreement, PSF hereby
grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
analyze, test, perform and/or display publicly, prepare derivative works,
distribute, and otherwise use Python 3.9 alone or in any derivative
version, provided, however, that PSF's License Agreement and PSF's notice of
copyright, i.e., "Copyright © 2001 Python Software Foundation; All Rights
Reserved" are retained in Python 3.9 alone or in any derivative version
prepared by Licensee.
3. In the event Licensee prepares a derivative work that is based on or
incorporates Python 3.9 or any part thereof, and wants to make the
derivative work available to others as provided herein, then Licensee hereby
agrees to include in any such work a brief summary of the changes made to Python
3.9.
4. PSF is making Python 3.9 available to Licensee on an "AS IS" basis.
PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF
EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR
WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE
USE OF PYTHON 3.9 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 3.9
FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF
MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 3.9, OR ANY DERIVATIVE
THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
6. This License Agreement will automatically terminate upon a material breach of
its terms and conditions.
7. Nothing in this License Agreement shall be deemed to create any relationship
of agency, partnership, or joint venture between PSF and Licensee. This License
Agreement does not grant permission to use PSF trademarks or trade name in a
trademark sense to endorse or promote products or services of Licensee, or any
third party.
8. By copying, installing or otherwise using Python 3.9, Licensee agrees
to be bound by the terms and conditions of this License Agreement.
## Features
* Easy to install Python runtime
* Supported by core CPython team
* Find Python, Pip and Idle on PATH
## Search Terms
* Python
* Scripting
* Interpreter
-4
View File
@@ -63,10 +63,6 @@
<Projects Include="python3dll.vcxproj" />
<!-- python3t.dll -->
<Projects Include="python3tdll.vcxproj" />
<!-- py[w].exe -->
<Projects Include="pylauncher.vcxproj;pywlauncher.vcxproj" />
<!-- pyshellext.dll -->
<Projects Include="pyshellext.vcxproj" />
<!-- Extension modules -->
<ExtensionModules Include="_asyncio;_decimal;_elementtree;_multiprocessing;_overlapped;pyexpat;_queue;_remote_debugging;select;unicodedata;winsound;_uuid;_wmi;_zoneinfo" />
<ExtensionModules Include="_ctypes" Condition="$(IncludeCTypes)" />
-108
View File
@@ -111,16 +111,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xxlimited", "xxlimited.vcxp
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testbuffer", "_testbuffer.vcxproj", "{A2697BD3-28C1-4AEC-9106-8B748639FD16}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pylauncher", "pylauncher.vcxproj", "{7B2727B5-5A3F-40EE-A866-43A13CD31446}"
ProjectSection(ProjectDependencies) = postProject
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782} = {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pywlauncher", "pywlauncher.vcxproj", "{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}"
ProjectSection(ProjectDependencies) = postProject
{7B2727B5-5A3F-40EE-A866-43A13CD31446} = {7B2727B5-5A3F-40EE-A866-43A13CD31446}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_freeze_module", "_freeze_module.vcxproj", "{19C0C13F-47CA-4432-AFF3-799A296A4DDC}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_overlapped", "_overlapped.vcxproj", "{EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}"
@@ -131,8 +121,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testmultiphase", "_testmul
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testsinglephase", "_testsinglephase.vcxproj", "{2097F1C1-597C-4167-93E3-656A7D6339B2}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pyshellext", "pyshellext.vcxproj", "{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testconsole", "_testconsole.vcxproj", "{B244E787-C445-441C-BDF4-5A4F1A3A1E51}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_asyncio", "_asyncio.vcxproj", "{384C224A-7474-476E-A01B-750EA7DE918C}"
@@ -1079,70 +1067,6 @@ Global
{A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|Win32.Build.0 = Release|Win32
{A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|x64.ActiveCfg = Release|x64
{A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|x64.Build.0 = Release|x64
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|ARM.ActiveCfg = Debug|ARM
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|ARM.Build.0 = Debug|ARM
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|ARM64.ActiveCfg = Debug|ARM64
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|ARM64.Build.0 = Debug|ARM64
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|Win32.ActiveCfg = Debug|Win32
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|Win32.Build.0 = Debug|Win32
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|x64.ActiveCfg = Debug|x64
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|x64.Build.0 = Debug|x64
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|ARM.Build.0 = PGInstrument|ARM
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|Win32.ActiveCfg = Release|Win32
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|Win32.Build.0 = Release|Win32
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|x64.ActiveCfg = Release|x64
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|x64.Build.0 = Release|x64
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|ARM.Build.0 = PGUpdate|ARM
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|Win32.ActiveCfg = Release|Win32
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|Win32.Build.0 = Release|Win32
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|x64.ActiveCfg = Release|x64
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|x64.Build.0 = Release|x64
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|ARM.ActiveCfg = Release|ARM
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|ARM.Build.0 = Release|ARM
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|ARM64.ActiveCfg = Release|ARM64
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|ARM64.Build.0 = Release|ARM64
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|Win32.ActiveCfg = Release|Win32
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|Win32.Build.0 = Release|Win32
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.ActiveCfg = Release|x64
{7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.Build.0 = Release|x64
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|ARM.ActiveCfg = Debug|ARM
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|ARM.Build.0 = Debug|ARM
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|ARM64.ActiveCfg = Debug|ARM64
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|ARM64.Build.0 = Debug|ARM64
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|Win32.ActiveCfg = Debug|Win32
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|Win32.Build.0 = Debug|Win32
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|x64.ActiveCfg = Debug|x64
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|x64.Build.0 = Debug|x64
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|ARM.Build.0 = PGInstrument|ARM
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|Win32.ActiveCfg = Release|Win32
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|Win32.Build.0 = Release|Win32
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|x64.ActiveCfg = Release|x64
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|x64.Build.0 = Release|x64
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|ARM.Build.0 = PGUpdate|ARM
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|Win32.ActiveCfg = Release|Win32
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|Win32.Build.0 = Release|Win32
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|x64.ActiveCfg = Release|x64
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|x64.Build.0 = Release|x64
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|ARM.ActiveCfg = Release|ARM
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|ARM.Build.0 = Release|ARM
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|ARM64.ActiveCfg = Release|ARM64
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|ARM64.Build.0 = Release|ARM64
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|Win32.ActiveCfg = Release|Win32
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|Win32.Build.0 = Release|Win32
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.ActiveCfg = Release|x64
{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.Build.0 = Release|x64
{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|ARM.ActiveCfg = Debug|ARM
{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|ARM.Build.0 = Debug|ARM
{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|ARM64.ActiveCfg = Debug|ARM64
@@ -1293,38 +1217,6 @@ Global
{2097F1C1-597C-4167-93E3-656A7D6339B2}.Release|Win32.Build.0 = Release|Win32
{2097F1C1-597C-4167-93E3-656A7D6339B2}.Release|x64.ActiveCfg = Release|x64
{2097F1C1-597C-4167-93E3-656A7D6339B2}.Release|x64.Build.0 = Release|x64
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|ARM.ActiveCfg = Debug|ARM
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|ARM.Build.0 = Debug|ARM
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|ARM64.ActiveCfg = Debug|ARM64
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|ARM64.Build.0 = Debug|ARM64
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|Win32.ActiveCfg = Debug|Win32
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|Win32.Build.0 = Debug|Win32
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|x64.ActiveCfg = Debug|x64
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|x64.Build.0 = Debug|x64
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|ARM.Build.0 = PGInstrument|ARM
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|Win32.Build.0 = PGInstrument|Win32
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|x64.ActiveCfg = PGInstrument|x64
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|x64.Build.0 = PGInstrument|x64
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|ARM.Build.0 = PGUpdate|ARM
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|Win32.Build.0 = PGUpdate|Win32
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|x64.Build.0 = PGUpdate|x64
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|ARM.ActiveCfg = Release|ARM
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|ARM.Build.0 = Release|ARM
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|ARM64.ActiveCfg = Release|ARM64
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|ARM64.Build.0 = Release|ARM64
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|Win32.ActiveCfg = Release|Win32
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|Win32.Build.0 = Release|Win32
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|x64.ActiveCfg = Release|x64
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|x64.Build.0 = Release|x64
{B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Debug|ARM.ActiveCfg = Debug|ARM
{B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Debug|ARM.Build.0 = Debug|ARM
{B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Debug|ARM64.ActiveCfg = Debug|ARM64
-114
View File
@@ -1,114 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGInstrument|ARM">
<Configuration>PGInstrument</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGInstrument|ARM64">
<Configuration>PGInstrument</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGInstrument|Win32">
<Configuration>PGInstrument</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGInstrument|x64">
<Configuration>PGInstrument</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGUpdate|ARM">
<Configuration>PGUpdate</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGUpdate|ARM64">
<Configuration>PGUpdate</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGUpdate|Win32">
<Configuration>PGUpdate</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGUpdate|x64">
<Configuration>PGUpdate</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{7B2727B5-5A3F-40EE-A866-43A13CD31446}</ProjectGuid>
<RootNamespace>pylauncher</RootNamespace>
<TargetName>py</TargetName>
<SupportPGO>false</SupportPGO>
</PropertyGroup>
<Import Project="python.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<PropertyGroup>
<MakeVersionInfoBeforeTarget>ClCompile</MakeVersionInfoBeforeTarget>
</PropertyGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="pyproject.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<AdditionalDependencies>shell32.lib;pathcch.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\PC\launcher2.c" />
</ItemGroup>
<ItemGroup>
<None Include="..\PC\icons\launcher.ico" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\PC\pylauncher.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
-28
View File
@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\PC\launcher.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\PC\icons\launcher.ico">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\PC\pylauncher.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>
-117
View File
@@ -1,117 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGInstrument|ARM">
<Configuration>PGInstrument</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGInstrument|ARM64">
<Configuration>PGInstrument</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGInstrument|Win32">
<Configuration>PGInstrument</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGInstrument|x64">
<Configuration>PGInstrument</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGUpdate|ARM">
<Configuration>PGUpdate</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGUpdate|ARM64">
<Configuration>PGUpdate</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGUpdate|Win32">
<Configuration>PGUpdate</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGUpdate|x64">
<Configuration>PGUpdate</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}</ProjectGuid>
<RootNamespace>pyshellext</RootNamespace>
<TargetName>pyshellext</TargetName>
<SupportPGO>false</SupportPGO>
</PropertyGroup>
<Import Project="python.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<PropertyGroup>
<MakeVersionInfoBeforeTarget>ClCompile</MakeVersionInfoBeforeTarget>
</PropertyGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="pyproject.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<AdditionalDependencies>version.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem>
<ModuleDefinitionFile>..\PC\pyshellext.def</ModuleDefinitionFile>
</Link>
<Midl>
<CompileInterface>true</CompileInterface>
</Midl>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\PC\pyshellext.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="..\PC\pyshellext.def" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\PC\pyshellext.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
-28
View File
@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\PC\pyshellext.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\PC\pyshellext.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\PC\pyshellext.def">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
</Project>
-114
View File
@@ -1,114 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGInstrument|ARM">
<Configuration>PGInstrument</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGInstrument|ARM64">
<Configuration>PGInstrument</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGInstrument|Win32">
<Configuration>PGInstrument</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGInstrument|x64">
<Configuration>PGInstrument</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGUpdate|ARM">
<Configuration>PGUpdate</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGUpdate|ARM64">
<Configuration>PGUpdate</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGUpdate|Win32">
<Configuration>PGUpdate</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="PGUpdate|x64">
<Configuration>PGUpdate</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}</ProjectGuid>
<RootNamespace>pywlauncher</RootNamespace>
<TargetName>pyw</TargetName>
<SupportPGO>false</SupportPGO>
</PropertyGroup>
<Import Project="python.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<PropertyGroup>
<MakeVersionInfoBeforeTarget>ClCompile</MakeVersionInfoBeforeTarget>
</PropertyGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="pyproject.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<AdditionalDependencies>shell32.lib;pathcch.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\PC\launcher2.c" />
</ItemGroup>
<ItemGroup>
<None Include="..\PC\icons\launcher.ico" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\PC\pylauncher.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
-28
View File
@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\PC\launcher.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\PC\icons\launcher.ico">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\PC\pylauncher.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>
+1 -11
View File
@@ -23,7 +23,7 @@ external dependencies. To build, simply run the "build.bat" script without
any arguments. After this succeeds, you can open the "pcbuild.sln"
solution in Visual Studio to continue development.
To build an installer package, refer to the README in the Tools/msi folder.
To build an installer package, refer to PC/layout.
The solution currently supports two platforms. The Win32 platform is
used to build standard x86-compatible 32-bit binaries, output into the
@@ -140,12 +140,6 @@ CPython in different ways:
pythonw
pythonw.exe, a variant of python.exe that doesn't open a Command
Prompt window
pylauncher
py.exe, the Python Launcher for Windows, see
https://docs.python.org/3/using/windows.html#launcher
pywlauncher
pyw.exe, a variant of py.exe that doesn't open a Command Prompt
window
_testembed
_testembed.exe, a small program that embeds Python for testing
purposes, used by test_capi.py
@@ -156,8 +150,6 @@ _freeze_module
_freeze_module.exe, used to regenerate frozen modules in Python
after changes have been made to the corresponding source files
(e.g. Lib\importlib\_bootstrap.py).
pyshellext
pyshellext.dll, the shell extension deployed with the launcher
python3dll
python3.dll, the PEP 384 Stable ABI dll
(not installed on free-threaded builds)
@@ -420,8 +412,6 @@ _testclinic_limited extension, the file Modules/_testclinic_limited.c:
* Save and exit Visual Studio.
* Add `;_testclinic_limited` to `<TestModules Include="...">` in
PCbuild\pcbuild.proj.
* Update "exts" in Tools\msi\lib\lib_files.wxs file or in
Tools\msi\test\test_files.wxs file (for tests).
* PC\layout\main.py needs updating if you add a test-only extension whose name
doesn't start with "_test".
* Add the extension to PCbuild\readme.txt (this file).
+1 -4
View File
@@ -110,10 +110,7 @@
<ClCompile Include="..\PC\venvlauncher.c" />
</ItemGroup>
<ItemGroup>
<None Include="..\PC\icons\launcher.ico" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\PC\pylauncher.rc" />
<ResourceCompile Include="..\PC\python_exe.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
+1 -6
View File
@@ -9,12 +9,7 @@
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="..\PC\icons\launcher.ico">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\PC\pylauncher.rc">
<ResourceCompile Include="..\PC\python_exe.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
+1 -4
View File
@@ -110,10 +110,7 @@
<ClCompile Include="..\PC\venvlauncher.c" />
</ItemGroup>
<ItemGroup>
<None Include="..\PC\icons\launcher.ico" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\PC\pylauncher.rc" />
<ResourceCompile Include="..\PC\python_exe.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
+1 -6
View File
@@ -14,12 +14,7 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\PC\icons\launcher.ico">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\PC\pylauncher.rc">
<ResourceCompile Include="..\PC\python_exe.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
+2 -2
View File
@@ -76,8 +76,8 @@ to macOS framework and universal builds. Refer to `Mac/README.rst
On Windows, see `PCbuild/readme.txt
<https://github.com/python/cpython/blob/main/PCbuild/readme.txt>`_.
To build Windows installer, see `Tools/msi/README.txt
<https://github.com/python/cpython/blob/main/Tools/msi/README.txt>`_.
To build Windows packages, see `PC/layout/README.md
<https://github.com/python/cpython/blob/main/PC/layout/README.md>`_.
If you wish, you can create a subdirectory and invoke configure from there.
For example::
-4
View File
@@ -34,10 +34,6 @@ jit Tooling for building the JIT.
lockbench Benchmarks for PyMutex and critical sections.
msi Support for packaging Python as an MSI package on Windows.
nuget Files for the NuGet package manager for .NET.
patchcheck Tools for checking and applying patches to the Python source code
and verifying the integrity of patch files.
-14
View File
@@ -117,7 +117,6 @@ class Outputs:
run_tests: bool = False
run_ubuntu: bool = False
run_wasi: bool = False
run_windows_msi: bool = False
run_windows_tests: bool = False
@@ -160,9 +159,6 @@ def compute_changes() -> None:
if outputs.run_docs:
print("Build documentation")
if outputs.run_windows_msi:
print("Build Windows MSI")
print(outputs)
write_github_output(outputs)
@@ -223,7 +219,6 @@ def process_changed_files(changed_files: Set[Path]) -> Outputs:
run_ci_fuzz_stdlib = False
run_docs = False
run_windows_tests = False
run_windows_msi = False
platforms_changed = set()
has_platform_specific_change = True
@@ -245,9 +240,6 @@ def process_changed_files(changed_files: Set[Path]) -> Outputs:
run_tests = True
run_windows_tests = True
continue
if file.name == "reusable-windows-msi.yml":
run_windows_msi = True
continue
if file.name == "reusable-macos.yml":
run_tests = True
platforms_changed.add("macos")
@@ -288,10 +280,6 @@ def process_changed_files(changed_files: Set[Path]) -> Outputs:
if doc_file:
run_docs = True
# Check for changed MSI installer-related files
if file.parts[:2] == ("Tools", "msi"):
run_windows_msi = True
# Check which platform specific tests to run
if run_tests:
if not has_platform_specific_change or not platforms_changed:
@@ -327,7 +315,6 @@ def process_changed_files(changed_files: Set[Path]) -> Outputs:
run_tests=run_tests,
run_ubuntu=run_ubuntu,
run_wasi=run_wasi,
run_windows_msi=run_windows_msi,
run_windows_tests=run_windows_tests,
)
@@ -342,7 +329,6 @@ def process_target_branch(outputs: Outputs, git_branch: str) -> Outputs:
if os.environ.get("GITHUB_EVENT_NAME", "").lower() == "workflow_dispatch":
outputs.run_docs = True
outputs.run_windows_msi = True
return outputs
+4 -2
View File
@@ -3,7 +3,9 @@ setlocal
pushd
@rem build both snapshot MSIs
call "%~dp0..\msi\build.bat" -x86 -x64
@rem The MSI project is gone, so instead we will just
@rem build and then do a default layout.
call "%~dp0..\..\PCbuild\build.bat" -e -k -v %*
call "%~dp0..\..\python.exe" "%~dp0..\..\PC\layout" --preset-default -o "%~dp0..\..\PCbuild\output"
popd
-530
View File
@@ -1,530 +0,0 @@
Quick Build Info
================
For testing, the installer should be built with the Tools/msi/build.bat
script:
build.bat [-x86] [-x64] [-ARM64] [--doc]
For an official release, the installer should be built with the
Tools/msi/buildrelease.bat script and environment variables:
set PYTHON=<path to Python 3.10 or later>
set SPHINXBUILD=<path to sphinx-build.exe>
set PATH=<path to Git (git.exe)>;%PATH%
buildrelease.bat [-x86] [-x64] [-ARM64] [-D] [-B]
[-o <output directory>] [-c <certificate name>]
See the Building the Installer section for more information.
Overview
========
Python is distributed on Windows as an installer that will configure the
user's system. This allows users to have a functioning copy of Python
without having to build it themselves.
The main tasks of the installer are:
* copy required files into the expected layout
* configure system settings so the installation can be located by
other programs
* add entry points for modifying, repairing and uninstalling Python
* make it easy to launch Python, its documentation, and IDLE
Each of these is discussed in a later section of this document.
Structure of the Installer
==========================
The installer is structured as a 'layout', which consists of a number of
CAB and MSI files and a single EXE.
The EXE is the main entry point into the installer. It contains the UI
and command-line logic, as well as the ability to locate and optionally
download other parts of the layout.
Each MSI contains the logic required to install a component or feature
of Python. These MSIs should not be launched directly by users. MSIs can
be embedded into the EXE or automatically downloaded as needed.
Each CAB contains the files making up a Python installation. CABs are
embedded into their associated MSI and are never seen by users.
MSIs are only required when the related feature or component is being
installed. When components are not selected for installation, the
associated MSI is not downloaded. This allows the installer to offer
options to install debugging symbols and binaries without increasing
the initial download size by separating them into their own MSIs.
Building the Installer
======================
Before building the installer, download the extra build dependencies
using Tools\msi\get_externals.bat. (Note that this is in addition to the
similarly named file in PCbuild.)
One of the dependencies used in the build process is WiX, a toolset that
allows developers to create installers for Windows Installer, the
Windows installation engine. If you're not using the copy of WiX
installed by Tools\msi\get_externals.bat, you'll need to set the
"WixInstallPath" environment variable before building.
Additionally, ensure that "MSVC v14x - VS 20xx C++ ARM64/ARM64EC build tools"
is selected under "Desktop Development with C++" in the "Visual Studio Installer",
even if you're not building on ARM64. This is required because we've upgraded
to WiX 3.14, which requires these tools for Python 3.10 and later versions.
For testing, the installer should be built with the Tools/msi/build.bat
script:
build.bat [-x86] [-x64] [-ARM64] [--doc] [--test-marker] [--pack]
This script will build the required configurations of Python and
generate an installer layout in PCbuild/(win32|amd64)/en-us.
Specify -x86, -x64 and/or -ARM64 to build for each platform. If none are
specified, both x64 and x86 will be built. Currently, both the debug and
release versions of Python are required for the installer.
Specify --doc to include the documentation files. Ensure %PYTHON% and
%SPHINXBUILD% are set when passing this option.
Specify --test-marker to build an installer that works side-by-side with
an official Python release. All registry keys and install locations will
include an extra marker to avoid overwriting files. This marker is
currently an 'x' prefix, but may change at any time.
Specify --pack to build an installer that does not require all MSIs to
be available alongside. This takes longer, but is easier to share.
For an official release, the installer should be built with the
Tools/msi/buildrelease.bat script:
set PYTHON=<path to Python 3.10 or later>
set SPHINXBUILD=<path to sphinx-build.exe>
set PATH=<path to Git (git.exe)>;%PATH%
buildrelease.bat [-x86] [-x64] [-ARM64] [-D] [-B]
[-o <output directory>] [-c <certificate name>]
Specify -x86, -x64 and/or -ARM64 to build for each platform. If none are
specified, both x64 and x86 will be built. Currently, both the debug and
release versions of Python are required for the installer.
Specify -D to skip rebuilding the documentation. The documentation is
required for a release and the build will fail if it is not available.
Ensure %PYTHON% and %SPHINXBUILD% are set if you omit this option.
Specify -B to skip rebuilding Python. This is useful to only rebuild the
installer layout after a previous call to buildrelease.bat.
Specify -o to set an output directory. The installer layouts will be
copied to platform-specific subdirectories of this path.
Specify -c to choose a code-signing certificate to be used for all the
signable binaries in Python as well as each file making up the
installer. Official releases of Python must be signed.
If WiX is not found on your system, it will be automatically downloaded
and extracted to the externals/ directory.
To manually build layouts of the installer, build one of the projects in
the bundle folder.
msbuild bundle\snapshot.wixproj
msbuild bundle\releaseweb.wixproj
msbuild bundle\releaselocal.wixproj
msbuild bundle\full.wixproj
snapshot.wixproj produces a test installer versioned based on the date.
releaseweb.wixproj produces a release installer that does not embed any
of the layout.
releaselocal.wixproj produces a release installer that embeds the files
required for a default installation.
full.wixproj produces a test installer that embeds the entire layout.
The following properties may be passed when building these projects.
/p:BuildForRelease=(true|false)
When true, adds extra verification to ensure a complete installer is
produced. Defaults to false.
/p:ReleaseUri=(any URI)
Used to generate unique IDs for the installers to allow side-by-side
installation. Forks of Python can use the same installer infrastructure
by providing a unique URI for this property. It does not need to be an
active internet address. Defaults to $(ComputerName).
Official releases use https://www.python.org/(architecture name)
/p:DownloadUrlBase=(any URI)
Specifies the base of a URL where missing parts of the installer layout
can be downloaded from. The build version and architecture will be
appended to create the full address. If omitted, missing components will
not be automatically downloaded.
/p:DownloadUrl=(any URI)
Specifies the full URL where missing parts of the installer layout can
be downloaded from. Should normally include '{2}', which will be
substituted for the filename. If omitted, missing components will not be
automatically downloaded. If specified, this value overrides
DownloadUrlBase.
/p:SigningCertificate=(certificate name)
Specifies the certificate to sign the installer layout with. If omitted,
the layout will not be signed.
/p:RebuildAll=(true|false)
When true, rebuilds all of the MSIs making up the layout. Defaults to
true.
Uploading the Installer
=======================
For official releases, the uploadrelease.bat script should be used.
You will require PuTTY so that plink.exe and pscp.exe can be used, and your
SSH key can be activated in pageant.exe. PuTTY should be either on your path
or in %ProgramFiles(x86)%\PuTTY.
To include signatures for each uploaded file, you will need gpg2.exe on your
path or have run get_externals.bat. You may also need to "gpg2.exe --import"
your key before running the upload script.
uploadrelease.bat --host <host> --user <username> [--dry-run] [--no-gpg]
The host is the URL to the server. This can be provided by the Release
Manager. You should be able to SSH to this address.
The username is your own username, which you have permission to SSH into
the server containing downloads.
Use --dry-run to display the generated upload commands without executing
them. Signatures for each file will be generated but not uploaded unless
--no-gpg is also passed.
Use --no-gpg to suppress signature generation and upload.
The default target directory (which appears in uploadrelease.proj) is
correct for official Python releases, but may be overridden with
--target <path> for other purposes. This path should generally not include
any version specifier, as that will be added automatically.
Modifying the Installer
=======================
The code for the installer is divided into three main groups: packages,
the bundle and the bootstrap application.
Packages
--------
Packages appear as subdirectories of Tools/msi (other than the bundle/
directory). The project file is a .wixproj and the build output is a
single MSI. Packages are built with the WiX Toolset. Some project files
share source files and use preprocessor directives to enable particular
features. These are typically used to keep the sources close when the
files are related, but produce multiple independent packages.
A package is the smallest element that may be independently installed or
uninstalled (as used in this installer). For example, the test suite has
its own package, as users can choose to add or remove it after the
initial installation.
All the files installed by a single package should be related, though
some packages may not install any files. For example, the pip package
executes the ensurepip package, but does not add or remove any of its
own files. (It is represented as a package because of its
installed/uninstalled nature, as opposed to the "precompile standard
library" option, for example.) Dependencies between packages are handled
by the bundle, but packages should detect when dependencies are missing
and raise an error.
Packages that include a lot of files may use an InstallFiles element in
the .wixproj file to generate sources. See lib/lib.wixproj for an
example, and msi.targets and csv_to_wxs.py for the implementation. This
element is also responsible for generating the code for cleaning up and
removing __pycache__ folders in any directory containing .py files.
All packages are built with the Tools/msi/common.wxs file, and so any
directory or property in this file may be referenced. Of particular
interest:
REGISTRYKEY (property)
The registry key for the current installation.
InstallDirectory (directory)
The root install directory for the current installation. Subdirectories
are also specified in this file (DLLs, Lib, etc.)
MenuDir (directory)
The Start Menu folder for the current installation.
UpgradeTable (property)
Every package should reference this property to include upgrade
information.
OptionalFeature (Component)
Packages that may be enabled or disabled should reference this component
and have an OPTIONAL_FEATURES entry in the bootstrap application to
properly handle Modify and Upgrade.
The .wxl_template file is specially handled by the build system for this
project to perform {{substitutions}} as defined in msi.targets. They
should be included in projects as <WxlTemplate> items, where .wxl files
are normally included as <EmbeddedResource> items.
Bundle
------
The bundle is compiled to the main EXE entry point that for most users
will represent the Python installer. It is built from Tools/msi/bundle
with packages references in Tools/msi/bundle/packagegroups.
Build logic for the bundle is in bundle.targets, but should be invoked
through one of the .wixproj files as described in Building the
Installer.
The UI is separated between Default.thm (UI layout), Default.wxl
(strings), bundle.wxs (properties) and the bootstrap application.
Bundle.wxs also contains the chain, which is the list of packages to
install and the order they should be installed in. These refer to named
package groups in bundle/packagegroups.
Each package group specifies one or more packages to install. Most
packages require two separate entries to support both per-user and
all-users installations. Because these reuse the same package, it does
not increase the overall size of the package.
Package groups refer to payload groups, which allow better control over
embedding and downloading files than the default settings. Whether files
are embedded and where they are downloaded from depends on settings
created by the project files.
Package references can include install conditions that determine when to
install the package. When a package is a dependency for others, the
condition should be crafted to ensure it is installed.
MSI packages are installed or uninstalled based on their current state
and the install condition. This makes them most suitable for features
that are clearly present or absent from the user's machine.
EXE packages are executed based on a customisable condition that can be
omitted. This makes them suitable for pre- or post-install tasks that
need to run regardless of whether features have been added or removed.
Bootstrap Application
---------------------
The bootstrap application is a C++ application that controls the UI and
installation. While it does not directly compile into the main EXE of
the installer, it forms the main active component. Most of the
installation functionality is provided by WiX, and so the bootstrap
application is predominantly responsible for the code behind the UI that
is defined in the Default.thm file. The bootstrap application code is in
bundle/bootstrap and is built automatically when building the bundle.
Installation Layout
===================
There are two installation layouts for Python on Windows, with the only
differences being supporting files. A layout is selected implicitly
based on whether the install is for all users of the machine or just for
the user performing the installation.
The default installation location when installing for all users is
"%ProgramFiles%\Python3X" for the 64-bit interpreter and
"%ProgramFiles(x86)%\Python3X-32" for the 32-bit interpreter. (Note that
the latter path is equivalent to "%ProgramFiles%\Python3X-32" when
running a 32-bit version of Windows.) This location requires
administrative privileges to install or later modify the installation.
The default installation location when installing for the current user
is "%LocalAppData%\Programs\Python\Python3X" for the 64-bit interpreter
and "%LocalAppData%\Programs\Python\Python3X-32" for the 32-bit
interpreter. Only the current user can access this location. This
provides a suitable level of protection against malicious modification
of Python's files.
(Default installation locations are set in Tools\msi\bundle\bundle.wxs.)
Within this install directory is the following approximate layout:
.\python[w].exe The core executable files
.\python3x.dll The core interpreter
.\python3.dll The stable ABI reference
.\DLLs Stdlib extensions (*.pyd) and dependencies
.\Doc Documentation (*.html)
.\include Development headers (*.h)
.\Lib Standard library
.\Lib\test Test suite
.\libs Development libraries (*.lib)
.\Scripts Launcher scripts (*.exe, *.py)
.\tcl Tcl dependencies (*.dll, *.tcl and others)
.\Tools Tool scripts (*.py)
When installed for all users, the following files are installed to
"%SystemRoot%" (typically "C:\Windows") to ensure they are always
available on PATH. (See Launching Python below.) For the current user,
they are installed in "%LocalAppData%\Programs\Python\PyLauncher".
.\py[w].exe PEP 397 launcher
System Settings
===============
On installation, registry keys are created so that other applications
can locate and identify installations of Python. The locations of these
keys vary based on the install type.
For 64-bit interpreters installed for all users, the root key is:
HKEY_LOCAL_MACHINE\Software\Python\PythonCore\3.X
For 32-bit interpreters installed for all users on a 64-bit operating
system, the root key is:
HKEY_LOCAL_MACHINE\Software\Wow6432Node\Python\PythonCore\3.X-32
For 32-bit interpreters installed for all users on a 32-bit operating
system, the root key is:
HKEY_LOCAL_MACHINE\Software\Python\PythonCore\3.X-32
For 64-bit interpreters installed for the current user:
HKEY_CURRENT_USER\Software\Python\PythonCore\3.X
For 32-bit interpreters installed for the current user:
HKEY_CURRENT_USER\Software\Python\PythonCore\3.X-32
When the core Python executables are installed, a key "InstallPath" is
created within the root key with its default value set to the
executable's install directory. A value named "ExecutablePath" is added
with the full path to the main Python interpreter, and a key
"InstallGroup" is created with its default value set to the product
name "Python 3.X".
When the Python standard library is installed, a key "PythonPath" is
created within the root key with its default value set to the full path
to the Lib folder followed by the path to the DLLs folder, separated by
a semicolon.
When the documentation is installed, a key "Help" is created within the
root key, with a subkey "Main Python Documentation" with its default
value set to the full path to the main index.html file.
The py.exe launcher is installed as part of a regular Python install,
but using a separate mechanism that allows it to more easily span
versions of Python. As a result, it has different root keys for its
registry entries:
When installed for all users on a 64-bit operating system, the
launcher's root key is:
HKEY_LOCAL_MACHINE\Software\Wow6432Node\Python\Launcher
When installed for all users on a 32-bit operating system, the
launcher's root key is:
HKEY_LOCAL_MACHINE\Software\Python\Launcher
When installed for the current user:
HKEY_CURRENT_USER\Software\Python\Launcher
When the launcher is installed, a key "InstallPath" is created within
its root key with its default value set to the launcher's install
directory. File associations are also created for .py, .pyw, .pyc and
.pyo files.
Launching Python
================
When a feature offering user entry points in the Start Menu is
installed, a folder "Python 3.X" is created. Every shortcut should be
created within this folder, and each shortcut should include the version
and platform to allow users to identify the shortcut in a search results
page.
The core Python executables creates a shortcut "Python 3.X (32-bit)" or
"Python 3.X (64-bit)" depending on the interpreter.
The documentation creates a shortcut "Python 3.X 32-bit Manuals" or
"Python 3.X 64-bit Manuals". The documentation is identical for all
platforms, but the shortcuts need to be separate to avoid uninstallation
conflicts.
Installing IDLE creates a shortcut "IDLE (Python 3.X 32-bit)" or "IDLE
(Python 3.X 64-bit)" depending on the interpreter.
For users who often launch Python from a Command Prompt, an option is
provided to add the directory containing python.exe to the user or
system PATH variable. If the option is selected, the install directory
and the Scripts directory will be added at the start of the system PATH
for an all users install and the user PATH for a per-user install.
When the user only has one version of Python installed, this will behave
as expected. However, because Windows searches the system PATH before
the user PATH, users cannot override a system-wide installation of
Python on their PATH. Further, because the installer can only prepend to
the path, later installations of Python will take precedence over
earlier installations, regardless of interpreter version.
Because it is not possible to automatically create a sensible PATH
configuration, users are recommended to use the py.exe launcher and
manually modify their PATH variable to add Scripts directories in their
preferred order. System-wide installations of Python should consider not
modifying PATH, or using an alternative technology to modify their
users' PATH variables.
The py.exe launcher is recommended because it uses a consistent and
sensible search order for Python installations. User installations are
preferred over system-wide installs, and later versions are preferred
regardless of installation order (with the exception that py.exe
currently prefers 2.x versions over 3.x versions without the -3 command
line argument).
For both 32-bit and 64-bit interpreters, the 32-bit version of the
launcher is installed. This ensures that the search order is always
consistent (as the 64-bit launcher is subtly different from the 32-bit
launcher) and also avoids the need to install it multiple times. Future
versions of Python will upgrade the launcher in-place, using Windows
Installer's upgrade functionality to avoid conflicts with earlier
installed versions.
When installed, file associations are created for .py, .pyc and .pyo
files to launch with py.exe and .pyw files to launch with pyw.exe. This
makes Python files respect shebang lines by default and also avoids
conflicts between multiple Python installations.
Repair, Modify and Uninstall
============================
After installation, Python may be modified, repaired or uninstalled by
running the original EXE again or via the Programs and Features applet
(formerly known as Add or Remove Programs).
Modifications allow features to be added or removed. The install
directory and kind (all users/single user) cannot be modified. Because
Windows Installer caches installation packages, removing features will
not require internet access unless the package cache has been corrupted
or deleted. Adding features that were not previously installed and are
not embedded or otherwise available will require internet access.
Repairing will rerun the installation for all currently installed
features, restoring files and registry keys that have been modified or
removed. This operation generally will not redownload any files unless
the cached packages have been corrupted or deleted.
Removing Python will clean up all the files and registry keys that were
created by the installer, as well as __pycache__ folders that are
explicitly handled by the installer. Python packages installed later
using a tool like pip will not be removed. Some components may be
installed by other installers and these will not be removed if another
product has a dependency on them.
-19
View File
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{12B59A06-37CC-4558-A9C8-DAE922E64EF3}</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion>
<OutputName>appendpath</OutputName>
<OutputType>Package</OutputType>
<SuppressIces>ICE71</SuppressIces>
</PropertyGroup>
<Import Project="..\msi.props" />
<ItemGroup>
<Compile Include="*.wxs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="*.wxl" />
</ItemGroup>
<Import Project="..\msi.targets" />
</Project>
-40
View File
@@ -1,40 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Language="!(loc.LCID)" Name="!(loc.Title)" Version="$(var.Version)" Manufacturer="!(loc.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
<Package InstallerVersion="500" Compressed="yes" InstallScope="perUser" />
<PropertyRef Id="DetectTargetDir" />
<PropertyRef Id="UpgradeTable" />
<PropertyRef Id="REGISTRYKEY" />
<Feature Id="DefaultFeature" AllowAdvertise="no" Title="!(loc.Title)" Description="!(loc.Description)">
<Component Id="AppendPath_CU" Directory="InstallDirectory" Guid="*">
<Condition>NOT ALLUSERS=1</Condition>
<RegistryKey Root="HKCU" Key="[REGISTRYKEY]">
<RegistryValue KeyPath="yes" Key="InstalledFeatures" Name="$(var.OptionalFeatureName)" Value="$(var.Version)" Type="string" />
</RegistryKey>
<CreateFolder Directory="Scripts" />
<RemoveFolder Id="Remove_Scripts_CU" Directory="Scripts" On="uninstall" />
<Environment Id="PATH_CU" Action="set" Name="PATH" Part="last" Value="[InstallDirectory]" />
<Environment Id="SCRIPTS_PATH_CU" Action="set" Name="PATH" Part="last" Value="[Scripts]" />
</Component>
<Component Id="AppendPath_LM" Directory="InstallDirectory" Guid="*">
<Condition>ALLUSERS=1</Condition>
<RegistryKey Root="HKLM" Key="[REGISTRYKEY]">
<RegistryValue KeyPath="yes" Key="InstalledFeatures" Name="$(var.OptionalFeatureName)" Value="$(var.Version)" Type="string" />
</RegistryKey>
<CreateFolder Directory="Scripts" />
<RemoveFolder Id="Remove_Scripts_LM" Directory="Scripts" On="uninstall" />
<Environment Id="PATH_LM" Action="set" Name="PATH" Part="last" Value="[InstallDirectory]" System="yes" />
<Environment Id="SCRIPTS_PATH_LM" Action="set" Name="PATH" Part="last" Value="[Scripts]" System="yes" />
<Environment Id="PY_PATHEXT_LM" Action="set" Name="PATHEXT" Part="last" Value=".PY" System="yes" />
<Environment Id="PYW_PATHEXT_LM" Action="set" Name="PATHEXT" Part="last" Value=".PYW" System="yes" />
</Component>
</Feature>
</Product>
</Wix>
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
<String Id="Descriptor">Append to Path</String>
<String Id="ShortDescriptor">AppendPath</String>
<String Id="NoPython">No !(loc.ProductName) installation was detected.</String>
</WixLocalization>
-103
View File
@@ -1,103 +0,0 @@
@echo off
setlocal
set D=%~dp0
set PCBUILD=%D%..\..\PCbuild\
set BUILDX86=
set BUILDX64=
set BUILDARM64=
set BUILDDOC=
set BUILDTEST=
set BUILDPACK=
set REBUILD=
:CheckOpts
if "%~1" EQU "-h" goto Help
if /I "%~1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts
if /I "%~1" EQU "-Win32" (set BUILDX86=1) && shift && goto CheckOpts
if /I "%~1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts
if /I "%~1" EQU "-arm64" (set BUILDARM64=1) && shift && goto CheckOpts
if "%~1" EQU "--doc" (set BUILDDOC=1) && shift && goto CheckOpts
if "%~1" EQU "--no-test-marker" (set BUILDTEST=) && shift && goto CheckOpts
if "%~1" EQU "--test-marker" (set BUILDTEST=--test-marker) && shift && goto CheckOpts
if "%~1" EQU "--pack" (set BUILDPACK=1) && shift && goto CheckOpts
if "%~1" EQU "-r" (set REBUILD=-r) && shift && goto CheckOpts
rem %IncludeFreethreaded% is recognised by the MSI build, but not the regular build.
rem We use it to build twice and then build the installer with its extra option
if /I "%~1" EQU "--disable-gil" (set IncludeFreethreaded=true) && shift && goto CheckOpts
if not defined BUILDX86 if not defined BUILDX64 if not defined BUILDARM64 (set BUILDX86=1) && (set BUILDX64=1)
call "%D%get_externals.bat"
call "%PCBUILD%find_msbuild.bat" %MSBUILD%
if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2)
if defined BUILDX86 call "%PCBUILD%build.bat" -p Win32 -d -e %REBUILD% %BUILDTEST%
if errorlevel 1 exit /B %ERRORLEVEL%
if defined BUILDX86 call "%PCBUILD%build.bat" -p Win32 -e %REBUILD% %BUILDTEST%
if errorlevel 1 exit /B %ERRORLEVEL%
if defined BUILDX64 call "%PCBUILD%build.bat" -p x64 -d -e %REBUILD% %BUILDTEST%
if errorlevel 1 exit /B %ERRORLEVEL%
if defined BUILDX64 call "%PCBUILD%build.bat" -p x64 -e %REBUILD% %BUILDTEST%
if errorlevel 1 exit /B %ERRORLEVEL%
if defined BUILDARM64 call "%PCBUILD%build.bat" -p ARM64 -d -e %REBUILD% %BUILDTEST%
if errorlevel 1 exit /B %ERRORLEVEL%
if defined BUILDARM64 call "%PCBUILD%build.bat" -p ARM64 -e %REBUILD% %BUILDTEST%
if errorlevel 1 exit /B %ERRORLEVEL%
if /I "%IncludeFreethreaded%"=="true" (
rem Cannot "exit /B" inside an if block because %ERRORLEVEL% will be wrong.
rem We just skip everything after the first "errorlevel 1" and then exit after
if defined BUILDX86 call "%PCBUILD%build.bat" -p Win32 -d -e %REBUILD% %BUILDTEST% --disable-gil
if not errorlevel 1 if defined BUILDX86 call "%PCBUILD%build.bat" -p Win32 -e %REBUILD% %BUILDTEST% --disable-gil
if not errorlevel 1 if defined BUILDX64 call "%PCBUILD%build.bat" -p x64 -d -e %REBUILD% %BUILDTEST% --disable-gil
if not errorlevel 1 if defined BUILDX64 call "%PCBUILD%build.bat" -p x64 -e %REBUILD% %BUILDTEST% --disable-gil
if not errorlevel 1 if defined BUILDARM64 call "%PCBUILD%build.bat" -p ARM64 -d -e %REBUILD% %BUILDTEST% --disable-gil
if not errorlevel 1 if defined BUILDARM64 call "%PCBUILD%build.bat" -p ARM64 -e %REBUILD% %BUILDTEST% --disable-gil
)
if errorlevel 1 exit /B %ERRORLEVEL%
if defined BUILDDOC call "%PCBUILD%..\Doc\make.bat" html
if errorlevel 1 exit /B %ERRORLEVEL%
rem Build the launcher MSI separately
%MSBUILD% "%D%launcher\launcher.wixproj" /p:Platform=x86
if errorlevel 1 exit /B %ERRORLEVEL%
set BUILD_CMD="%D%bundle\snapshot.wixproj"
if defined BUILDTEST (
set BUILD_CMD=%BUILD_CMD% /p:UseTestMarker=true
)
if defined BUILDPACK (
set BUILD_CMD=%BUILD_CMD% /p:Pack=true
)
if defined REBUILD (
set BUILD_CMD=%BUILD_CMD% /t:Rebuild
)
if defined BUILDX86 %MSBUILD% /p:Platform=x86 %BUILD_CMD%
if errorlevel 1 exit /B %ERRORLEVEL%
if defined BUILDX64 %MSBUILD% /p:Platform=x64 %BUILD_CMD%
if errorlevel 1 exit /B %ERRORLEVEL%
if defined BUILDARM64 %MSBUILD% /p:Platform=ARM64 %BUILD_CMD%
if errorlevel 1 exit /B %ERRORLEVEL%
exit /B 0
:Help
echo build.bat [-x86] [-x64] [-arm64] [--doc] [-h] [--test-marker] [--pack] [-r]
echo.
echo -x86 Build x86 installers
echo -x64 Build x64 installers
echo -ARM64 Build ARM64 installers
echo --doc Build documentation
echo --test-marker Build with test markers
echo --no-test-marker Build without test markers (default)
echo --pack Embed core MSIs into installer
echo -r Rebuild rather than incremental build
-261
View File
@@ -1,261 +0,0 @@
@setlocal
@echo off
rem This script is intended for building official releases of Python.
rem To use it to build alternative releases, you should clone this file
rem and modify the following three URIs.
rem These two will ensure that your release can be installed
rem alongside an official Python release, by modifying the GUIDs used
rem for all components.
rem
rem The following substitutions will be applied to the release URI:
rem Variable Description Example
rem {arch} architecture amd64, win32
rem Do not change the scheme to https. Otherwise, releases built with this
rem script will not be upgradable to/from official releases of Python.
set RELEASE_URI=http://www.python.org/{arch}
rem This is the URL that will be used to download installation files.
rem The files available from the default URL *will* conflict with your
rem installer. Trust me, you don't want them, even if it seems like a
rem good idea.
rem
rem The following substitutions will be applied to the download URL:
rem Variable Description Example
rem {version} version number 3.5.0
rem {arch} architecture amd64, win32
rem {releasename} release name a1, b2, rc3 (or blank for final)
rem {msi} MSI filename core.msi
set DOWNLOAD_URL=https://www.python.org/ftp/python/{version}/{arch}{releasename}/{msi}
set D=%~dp0
set PCBUILD=%D%..\..\PCbuild\
if NOT DEFINED Py_OutDir set Py_OutDir=%PCBUILD%
set EXTERNALS=%D%..\..\externals\windows-installer\
set BUILDX86=
set BUILDX64=
set BUILDARM64=
set TARGET=Rebuild
set TESTTARGETDIR=
set PGO=-m test -q --pgo
set BUILDMSI=1
set BUILDNUGET=1
set BUILDZIP=1
:CheckOpts
if "%1" EQU "-h" goto Help
if "%1" EQU "-c" (set CERTNAME=%~2) && shift && shift && goto CheckOpts
if "%1" EQU "--certificate" (set CERTNAME=%~2) && shift && shift && goto CheckOpts
if "%1" EQU "-o" (set OUTDIR=%~2) && shift && shift && goto CheckOpts
if "%1" EQU "--out" (set OUTDIR=%~2) && shift && shift && goto CheckOpts
if "%1" EQU "-D" (set SKIPDOC=1) && shift && goto CheckOpts
if "%1" EQU "--skip-doc" (set SKIPDOC=1) && shift && goto CheckOpts
if "%1" EQU "-B" (set SKIPBUILD=1) && shift && goto CheckOpts
if "%1" EQU "--skip-build" (set SKIPBUILD=1) && shift && goto CheckOpts
if "%1" EQU "--download" (set DOWNLOAD_URL=%~2) && shift && shift && goto CheckOpts
if "%1" EQU "--test" (set TESTTARGETDIR=%~2) && shift && shift && goto CheckOpts
if "%1" EQU "-b" (set TARGET=Build) && shift && goto CheckOpts
if "%1" EQU "--build" (set TARGET=Build) && shift && goto CheckOpts
if /I "%1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts
if /I "%1" EQU "-Win32" (set BUILDX86=1) && shift && goto CheckOpts
if /I "%1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts
if /I "%1" EQU "-arm64" (set BUILDARM64=1) && shift && goto CheckOpts
if "%1" EQU "--pgo" (set PGO=%~2) && shift && shift && goto CheckOpts
if "%1" EQU "--skip-pgo" (set PGO=) && shift && goto CheckOpts
if "%1" EQU "--skip-nuget" (set BUILDNUGET=) && shift && goto CheckOpts
if "%1" EQU "--skip-zip" (set BUILDZIP=) && shift && goto CheckOpts
if "%1" EQU "--skip-msi" (set BUILDMSI=) && shift && goto CheckOpts
if "%1" NEQ "" echo Invalid option: "%1" && exit /B 1
if not defined BUILDX86 if not defined BUILDX64 if not defined BUILDARM64 (set BUILDX86=1) && (set BUILDX64=1)
if not exist "%GIT%" where git > "%TEMP%\git.loc" 2> nul && set /P GIT= < "%TEMP%\git.loc" & del "%TEMP%\git.loc"
if not exist "%GIT%" echo Cannot find Git on PATH && exit /B 1
call "%D%get_externals.bat"
call "%PCBUILD%find_msbuild.bat" %MSBUILD%
if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2)
:builddoc
if "%SKIPBUILD%" EQU "1" goto skipdoc
if "%SKIPDOC%" EQU "1" goto skipdoc
call "%D%..\..\doc\make.bat" html
if errorlevel 1 exit /B %ERRORLEVEL%
:skipdoc
if defined BUILDX86 (
call :build x86
if errorlevel 1 exit /B %ERRORLEVEL%
)
if defined BUILDX64 (
call :build x64 "%PGO%"
if errorlevel 1 exit /B %ERRORLEVEL%
)
if defined BUILDARM64 (
call :build ARM64
if errorlevel 1 exit /B %ERRORLEVEL%
)
if defined TESTTARGETDIR (
call "%D%testrelease.bat" -t "%TESTTARGETDIR%"
if errorlevel 1 exit /B %ERRORLEVEL%
)
exit /B 0
:build
@setlocal
@echo off
if "%1" EQU "x86" (
set PGO=
set BUILD=%Py_OutDir%win32\
set BUILD_PLAT=Win32
set OUTDIR_PLAT=win32
set OBJDIR_PLAT=x86
) else if "%1" EQU "x64" (
set BUILD=%Py_OutDir%amd64\
set PGO=%~2
set BUILD_PLAT=x64
set OUTDIR_PLAT=amd64
set OBJDIR_PLAT=x64
) else if "%1" EQU "ARM64" (
set BUILD=%Py_OutDir%arm64\
set PGO=%~2
set BUILD_PLAT=ARM64
set OUTDIR_PLAT=arm64
set OBJDIR_PLAT=arm64
) else (
echo Unknown platform %1
exit /B 1
)
if exist "%BUILD%en-us" (
echo Deleting %BUILD%en-us
rmdir /q/s "%BUILD%en-us"
if errorlevel 1 exit /B %ERRORLEVEL%
)
if exist "%D%obj\Debug_%OBJDIR_PLAT%" (
echo Deleting "%D%obj\Debug_%OBJDIR_PLAT%"
rmdir /q/s "%D%obj\Debug_%OBJDIR_PLAT%"
if errorlevel 1 exit /B %ERRORLEVEL%
)
if exist "%D%obj\Release_%OBJDIR_PLAT%" (
echo Deleting "%D%obj\Release_%OBJDIR_PLAT%"
rmdir /q/s "%D%obj\Release_%OBJDIR_PLAT%"
if errorlevel 1 exit /B %ERRORLEVEL%
)
if not "%CERTNAME%" EQU "" (
set CERTOPTS="/p:SigningCertificate=%CERTNAME%"
) else (
set CERTOPTS=
)
if not "%PGO%" EQU "" (
set PGOOPTS=--pgo-job "%PGO%"
) else (
set PGOOPTS=
)
if not "%SKIPBUILD%" EQU "1" (
@echo call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -t %TARGET% %PGOOPTS% %CERTOPTS%
@call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -t %TARGET% %PGOOPTS% %CERTOPTS%
@if errorlevel 1 exit /B %ERRORLEVEL%
@rem build.bat turns echo back on, so we disable it again
@echo off
@echo call "%PCBUILD%build.bat" -d -e -p %BUILD_PLAT% -t %TARGET%
@call "%PCBUILD%build.bat" -d -e -p %BUILD_PLAT% -t %TARGET%
@if errorlevel 1 exit /B %ERRORLEVEL%
@rem build.bat turns echo back on, so we disable it again
@echo off
)
if "%OUTDIR_PLAT%" EQU "win32" (
%MSBUILD% "%D%launcher\launcher.wixproj" /p:Platform=x86 %CERTOPTS% /p:ReleaseUri=%RELEASE_URI%
if errorlevel 1 exit /B %ERRORLEVEL%
) else if not exist "%Py_OutDir%win32\en-us\launcher.msi" (
%MSBUILD% "%D%launcher\launcher.wixproj" /p:Platform=x86 %CERTOPTS% /p:ReleaseUri=%RELEASE_URI%
if errorlevel 1 exit /B %ERRORLEVEL%
)
set BUILDOPTS=/p:Platform=%1 /p:BuildForRelease=true /p:DownloadUrl=%DOWNLOAD_URL% /p:DownloadUrlBase=%DOWNLOAD_URL_BASE% /p:ReleaseUri=%RELEASE_URI%
if defined BUILDMSI (
%MSBUILD% "%D%bundle\releaselocal.wixproj" /t:Rebuild %BUILDOPTS% %CERTOPTS% /p:RebuildAll=true
if errorlevel 1 exit /B %ERRORLEVEL%
)
if defined BUILDZIP (
if "%BUILD_PLAT%" EQU "ARM64" (
echo Skipping embeddable ZIP generation for ARM64 platform
) else (
%MSBUILD% "%D%make_zip.proj" /t:Build %BUILDOPTS% %CERTOPTS% /p:OutputPath="%BUILD%en-us"
if errorlevel 1 exit /B %ERRORLEVEL%
)
)
if defined BUILDNUGET (
if "%BUILD_PLAT%" EQU "ARM64" (
echo Skipping Nuget package generation for ARM64 platform
) else (
%MSBUILD% "%D%..\nuget\make_pkg.proj" /t:Build /p:Configuration=Release /p:Platform=%1 /p:OutputPath="%BUILD%en-us"
if errorlevel 1 exit /B %ERRORLEVEL%
)
)
if not "%OUTDIR%" EQU "" (
mkdir "%OUTDIR%\%OUTDIR_PLAT%"
mkdir "%OUTDIR%\%OUTDIR_PLAT%\binaries"
mkdir "%OUTDIR%\%OUTDIR_PLAT%\symbols"
robocopy "%BUILD%en-us" "%OUTDIR%\%OUTDIR_PLAT%" /XF "*.wixpdb"
robocopy "%BUILD%\" "%OUTDIR%\%OUTDIR_PLAT%\binaries" *.exe *.dll *.pyd /XF "_test*" /XF "*_d.*" /XF "_freeze*" /XF "tcl*" /XF "tk*" /XF "*_test.*"
robocopy "%BUILD%\" "%OUTDIR%\%OUTDIR_PLAT%\symbols" *.pdb /XF "_test*" /XF "*_d.*" /XF "_freeze*" /XF "tcl*" /XF "tk*" /XF "*_test.*"
)
exit /B 0
:Help
echo buildrelease.bat [--out DIR] [-x86] [-x64] [-arm64] [--certificate CERTNAME] [--build] [--pgo COMMAND]
echo [--skip-build] [--skip-doc] [--skip-nuget] [--skip-zip] [--skip-pgo]
echo [--download DOWNLOAD URL] [--test TARGETDIR]
echo [-h]
echo.
echo --out (-o) Specify an additional output directory for installers
echo -x86 Build x86 installers
echo -x64 Build x64 installers
echo -arm64 Build ARM64 installers
echo --build (-b) Incrementally build Python rather than rebuilding
echo --skip-build (-B) Do not build Python (just do the installers)
echo --skip-doc (-D) Do not build documentation
echo --pgo Specify PGO command for x64 installers
echo --skip-pgo Build x64 installers without using PGO
echo --skip-msi Do not build executable/MSI packages
echo --skip-nuget Do not build Nuget packages
echo --skip-zip Do not build embeddable package
echo --download Specify the full download URL for MSIs
echo --test Specify the test directory to run the installer tests
echo -h Display this help information
echo.
echo If no architecture is specified, all architectures will be built.
echo If --test is not specified, the installer tests are not run.
echo.
echo For the --pgo option, any Python command line can be used, or 'default' to
echo use the default task (-m test --pgo).
echo.
echo x86 and ARM64 builds will never use PGO. ARM64 builds will never generate
echo embeddable or Nuget packages.
echo.
echo The following substitutions will be applied to the download URL:
echo Variable Description Example
echo {version} version number 3.5.0
echo {arch} architecture amd64, win32
echo {releasename} release name a1, b2, rc3 (or blank for final)
echo {msi} MSI filename core.msi
-28
View File
@@ -1,28 +0,0 @@
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://schemas.microsoft.com/wix/2006/localization">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!--
** No longer need this change, but I'm leaving the snippets here as an example
** in case we need to add another override in the future.
<xsl:template match="*[local-name()='String' and @Id='InstallButtonNote']">
<String Id="InstallButtonNote">[TargetDir]
Includes IDLE, pip and documentation
Creates shortcuts but no file associations</String>
</xsl:template>
<xsl:template match="*[local-name()='String' and @Id='Include_launcherHelp']">
<String Id="Include_launcherHelp">(The 'py' launcher is currently unavailable on ARM64.)</String>
</xsl:template>
-->
</xsl:stylesheet>
-141
View File
@@ -1,141 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Theme xmlns="http://wixtoolset.org/schemas/thmutil/2010">
<Window Width="670" Height="422" HexStyle="100a0000" FontId="0">#(loc.Caption)</Window>
<Font Id="0" Height="-14" Weight="500" Foreground="000000" Background="ffffff">Segoe UI</Font>
<Font Id="1" Height="-26" Weight="500" Foreground="000000" Background="ffffff">Segoe UI</Font>
<Font Id="2" Height="-24" Weight="500" Foreground="808080" Background="ffffff">Segoe UI</Font>
<Font Id="3" Height="-14" Weight="500" Foreground="000000" Background="ffffff">Segoe UI</Font>
<Font Id="4" Height="-14" Weight="500" Foreground="ff0000" Background="ffffff" Underline="yes">Segoe UI</Font>
<Font Id="5" Height="-14" Weight="500" Foreground="808080" Background="ffffff">Segoe UI</Font>
<Font Id="6" Height="-14" Weight="700" Foreground="000000" Background="ffffff">Segoe UI</Font>
<Page Name="Help">
<Text X="185" Y="11" Width="-11" Height="36" FontId="1" DisablePrefix="yes">#(loc.HelpHeader)</Text>
<Image X="0" Y="0" Width="178" Height="382" ImageFile="SideBar.png"/>
<Hypertext X="185" Y="50" Width="-11" Height="-35" FontId="3" DisablePrefix="yes">#(loc.HelpText)</Hypertext>
<Button Name="SuccessCancelButton" X="-11" Y="-11" Width="85" Height="27" TabStop="yes" FontId="0">#(loc.CloseButton)</Button>
</Page>
<Page Name="Install">
<Text X="185" Y="11" Width="-11" Height="36" FontId="1" DisablePrefix="yes">#(loc.InstallHeader)</Text>
<Image X="0" Y="0" Width="178" Height="382" ImageFile="SideBar.png"/>
<Text X="185" Y="50" Width="-11" Height="50" FontId="3" TabStop="yes">#(loc.InstallMessage)</Text>
<Hypertext X="185" Y="100" Width="-11" Height="40" FontId="6" DisablePrefix="yes">#(loc.DeprecationMessage)</Hypertext>
<Button Name="InstallButton" X="185" Y="141" Width="-11" Height="109" TabStop="yes" FontId="3" HexStyle="0xE">#(loc.InstallButton)</Button>
<Button Name="InstallCustomButton" X="185" Y="251" Width="-11" Height="59" TabStop="yes" FontId="3" HexStyle="0xE">#(loc.InstallCustomButton)</Button>
<Checkbox Name="InstallLauncherAllUsers" X="185" Y="-37" Width="-100" Height="24" TabStop="yes" FontId="3">#(loc.ShortInstallLauncherAllUsersLabel)</Checkbox>
<Checkbox Name="PrependPath" X="185" Y="-13" Width="-100" Height="24" TabStop="yes" FontId="3">#(loc.ShortPrependPathLabel)</Checkbox>
<Button Name="InstallCancelButton" X="-11" Y="-11" Width="85" Height="27" TabStop="yes" FontId="0">#(loc.CancelButton)</Button>
</Page>
<Page Name="Upgrade">
<Text X="185" Y="11" Width="-11" Height="36" FontId="1" DisablePrefix="yes">#(loc.InstallUpgradeHeader)</Text>
<Image X="0" Y="0" Width="178" Height="382" ImageFile="SideBar.png"/>
<Text X="185" Y="50" Width="-11" Height="50" FontId="3" TabStop="yes">#(loc.InstallUpgradeMessage)</Text>
<Button Name="InstallUpgradeButton" X="185" Y="101" Width="-11" Height="129" TabStop="yes" FontId="3" HexStyle="0xE">#(loc.InstallUpgradeButton)</Button>
<Button Name="InstallUpgradeCustomButton" X="185" Y="241" Width="-11" Height="59" TabStop="yes" FontId="3" HexStyle="0xE">#(loc.InstallUpgradeCustomButton)</Button>
<Button Name="InstallCancelButton" X="-11" Y="-11" Width="85" Height="27" TabStop="yes" FontId="0">#(loc.CancelButton)</Button>
</Page>
<Page Name="SimpleInstall">
<Text X="185" Y="11" Width="-11" Height="36" FontId="1" DisablePrefix="yes">#(loc.InstallHeader)</Text>
<Image X="0" Y="0" Width="178" Height="382" ImageFile="SideBar.png"/>
<Button Name="InstallSimpleButton" X="185" Y="101" Width="-11" Height="129" TabStop="yes" FontId="3" HideWhenDisabled="yes" HexStyle="0xF">#(loc.InstallSimpleButton)</Button>
<Button Name="InstallCancelButton" X="-11" Y="-11" Width="85" Height="27" TabStop="yes" FontId="0">#(loc.CancelButton)</Button>
</Page>
<Page Name="Custom1">
<Text X="185" Y="11" Width="-11" Height="36" FontId="1" DisablePrefix="yes">#(loc.Custom1Header)</Text>
<Image X="0" Y="0" Width="178" Height="382" ImageFile="SideBar.png"/>
<Checkbox Name="Include_doc" X="185" Y="51" Width="-11" Height="24" TabStop="yes" FontId="3" HideWhenDisabled="no">#(loc.Include_docLabel)</Checkbox>
<Text X="205" Y="76" Width="-11" Height="24" TabStop="no" FontId="5">#(loc.Include_docHelpLabel)</Text>
<Checkbox Name="Include_pip" X="185" Y="101" Width="-11" Height="24" TabStop="yes" FontId="3" HideWhenDisabled="no">#(loc.Include_pipLabel)</Checkbox>
<Text X="205" Y="126" Width="-11" Height="24" TabStop="no" FontId="5">#(loc.Include_pipHelpLabel)</Text>
<Checkbox Name="Include_tcltk" X="185" Y="151" Width="-11" Height="24" TabStop="yes" FontId="3" HideWhenDisabled="no">#(loc.Include_tcltkLabel)</Checkbox>
<Text Name="Include_tcltkLabel" X="205" Y="176" Width="-11" Height="24" TabStop="no" FontId="5">#(loc.Include_tcltkHelpLabel)</Text>
<Checkbox Name="Include_test" X="185" Y="201" Width="-11" Height="24" TabStop="yes" FontId="3" HideWhenDisabled="no">#(loc.Include_testLabel)</Checkbox>
<Text X="205" Y="226" Width="-11" Height="24" TabStop="no" FontId="5">#(loc.Include_testHelpLabel)</Text>
<Checkbox Name="Include_launcher" X="185" Y="251" Width="100" Height="24" TabStop="yes" FontId="3" HideWhenDisabled="no">#(loc.Include_launcherLabel)</Checkbox>
<Checkbox Name="CustomInstallLauncherAllUsers" X="285" Y="251" Width="-11" Height="24" TabStop="yes" FontId="3">#(loc.InstallLauncherAllUsersLabel)</Checkbox>
<Text Name="Include_launcherHelp" X="205" Y="276" Width="-11" Height="24" TabStop="no" FontId="5"></Text>
<Button Name="Custom1BackButton" X="185" Y="-11" Width="85" Height="27" TabStop="yes" FontId="0">#(loc.CustomBackButton)</Button>
<Button Name="CustomNextButton" X="-101" Y="-11" Width="85" Height="27" TabStop="yes" FontId="0">#(loc.CustomNextButton)</Button>
<Button Name="Custom1CancelButton" X="-11" Y="-11" Width="85" Height="27" TabStop="yes" FontId="0">#(loc.CancelButton)</Button>
</Page>
<Page Name="Custom2">
<Text X="185" Y="11" Width="-11" Height="36" FontId="1" DisablePrefix="yes">#(loc.Custom2Header)</Text>
<Image X="0" Y="0" Width="178" Height="382" ImageFile="SideBar.png"/>
<Checkbox Name="InstallAllUsers" X="185" Y="51" Width="-11" Height="24" TabStop="yes" FontId="3" HideWhenDisabled="no">#(loc.InstallAllUsersLabel)</Checkbox>
<Checkbox Name="AssociateFiles" X="185" Y="76" Width="-11" Height="24" TabStop="yes" FontId="3" HideWhenDisabled="no">#(loc.AssociateFilesLabel)</Checkbox>
<Checkbox Name="Shortcuts" X="185" Y="101" Width="-11" Height="24" TabStop="yes" FontId="3" HideWhenDisabled="no">#(loc.ShortcutsLabel)</Checkbox>
<Checkbox Name="PrependPath" X="185" Y="126" Width="-11" Height="24" TabStop="yes" FontId="3" HideWhenDisabled="no">#(loc.PrependPathLabel)</Checkbox>
<Checkbox Name="CompileAll" X="185" Y="151" Width="-11" Height="24" TabStop="yes" FontId="3" HideWhenDisabled="no">#(loc.PrecompileLabel)</Checkbox>
<Checkbox Name="Include_symbols" X="185" Y="176" Width="-11" Height="24" TabStop="yes" FontId="3" HideWhenDisabled="no">#(loc.Include_symbolsLabel)</Checkbox>
<Checkbox Name="Include_debug" X="185" Y="201" Width="-11" Height="24" TabStop="yes" FontId="3" HideWhenDisabled="no">#(loc.Include_debugLabel)</Checkbox>
<Checkbox Name="Include_freethreaded" X="185" Y="226" Width="-11" Height="24" TabStop="yes" FontId="3" HideWhenDisabled="yes">#(loc.Include_freethreadedLabel)</Checkbox>
<Text X="185" Y="256" Width="-11" Height="17" FontId="3">#(loc.CustomLocationLabel)</Text>
<Editbox Name="TargetDir" X="185" Y="277" Width="-101" Height="27" TabStop="yes" FontId="3" FileSystemAutoComplete="yes" />
<Button Name="CustomBrowseButton" X="-11" Y="276" Width="85" Height="27" TabStop="yes" FontId="3">#(loc.CustomBrowseButton)</Button>
<Text Name="CustomBrowseButtonLabel" X="185" Y="306" Width="-91" Height="35" FontId="5" HideWhenDisabled="yes">#(loc.CustomLocationHelpLabel)</Text>
<Button Name="Custom2BackButton" X="185" Y="-11" Width="85" Height="27" TabStop="yes" FontId="0">#(loc.CustomBackButton)</Button>
<Button Name="CustomInstallButton" X="-101" Y="-11" Width="95" Height="27" TabStop="yes" FontId="0">#(loc.CustomInstallButton)</Button>
<Button Name="Custom2CancelButton" X="-11" Y="-11" Width="85" Height="27" TabStop="yes" FontId="0">#(loc.CancelButton)</Button>
</Page>
<Page Name="Progress">
<Text X="185" Y="11" Width="-11" Height="36" FontId="1" DisablePrefix="yes">#(loc.ProgressHeader)</Text>
<Image X="0" Y="0" Width="178" Height="382" ImageFile="SideBar.png"/>
<Text X="185" Y="111" Width="-11" Height="20" FontId="3" DisablePrefix="yes">#(loc.ProgressLabel)</Text>
<Text Name="OverallProgressPackageText" X="185" Y="146" Width="-11" Height="20" FontId="3" DisablePrefix="yes">#(loc.OverallProgressPackageText)</Text>
<Progressbar Name="OverallCalculatedProgressbar" X="185" Y="171" Width="-11" Height="24" />
<Button Name="ProgressCancelButton" X="-11" Y="-11" Width="95" Height="27" TabStop="yes" FontId="0">#(loc.CancelButton)</Button>
</Page>
<Page Name="Modify">
<Text X="185" Y="11" Width="-11" Height="36" FontId="1" DisablePrefix="yes">#(loc.ModifyHeader)</Text>
<Image X="0" Y="0" Width="178" Height="382" ImageFile="SideBar.png"/>
<Button Name="ModifyButton" X="185" Y="101" Width="-11" Height="59" TabStop="yes" FontId="3" HexStyle="0xF">#(loc.ModifyModifyButton)</Button>
<Button Name="RepairButton" X="185" Y="171" Width="-11" Height="59" TabStop="yes" FontId="3" HexStyle="0xE">#(loc.ModifyRepairButton)</Button>
<Button Name="UninstallButton" X="185" Y="241" Width="-11" Height="59" TabStop="yes" FontId="3" HexStyle="0xE">#(loc.ModifyUninstallButton)</Button>
<Button Name="ModifyCancelButton" X="-11" Y="-11" Width="85" Height="27" TabStop="yes" FontId="0">#(loc.CancelButton)</Button>
</Page>
<Page Name="Success">
<Text X="185" Y="11" Width="-11" Height="36" FontId="1" DisablePrefix="yes">#(loc.SuccessHeader)</Text>
<Image X="0" Y="0" Width="178" Height="382" ImageFile="SideBar.png"/>
<Hypertext Name="SuccessText" X="205" Y="71" Width="-71" Height="160" FontId="3" DisablePrefix="yes"></Hypertext>
<Button Name="SuccessMaxPathButton" X="185" Y="-80" Width="-11" Height="81" TabStop="yes" FontId="3" HexStyle="0xE" HideWhenDisabled="yes">#(loc.SuccessMaxPathButton)</Button>
<Text Name="SuccessRestartText" X="205" Y="-40" Width="-11" Height="34" FontId="3" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.SuccessRestartText)</Text>
<Button Name="SuccessRestartButton" X="-101" Y="-11" Width="85" Height="27" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.SuccessRestartButton)</Button>
<Button Name="SuccessCancelButton" X="-11" Y="-11" Width="85" Height="27" TabStop="yes" FontId="0">#(loc.CloseButton)</Button>
</Page>
<Page Name="Failure">
<Text X="185" Y="11" Width="-11" Height="36" FontId="1" DisablePrefix="yes">#(loc.FailureHeader)</Text>
<Image X="0" Y="0" Width="178" Height="382" ImageFile="SideBar.png"/>
<Hypertext Name="FailureLogFileLink" X="205" Y="71" Width="-11" Height="60" FontId="3" TabStop="yes" HideWhenDisabled="yes">#(loc.FailureHyperlinkLogText)</Hypertext>
<Hypertext Name="FailureMessageText" X="205" Y="151" Width="-11" Height="120" FontId="3" TabStop="yes" HideWhenDisabled="yes"></Hypertext>
<Text Name="FailureRestartText" X="205" Y="-40" Width="-11" Height="34" FontId="3" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureRestartText)</Text>
<Button Name="FailureRestartButton" X="-101" Y="-11" Width="85" Height="27" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.FailureRestartButton)</Button>
<Button Name="FailureCancelButton" X="-11" Y="-11" Width="85" Height="27" TabStop="yes" FontId="0">#(loc.CloseButton)</Button>
</Page>
</Theme>
-133
View File
@@ -1,133 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<WixLocalization Culture="en-us" Language="1033" xmlns="http://schemas.microsoft.com/wix/2006/localization">
<String Id="Caption">[WixBundleName] Setup</String>
<String Id="Installing">Installing</String>
<String Id="Installation">Setup</String>
<String Id="Modifying">Updating</String>
<String Id="Modification">Modify</String>
<String Id="Repairing">Repairing</String>
<String Id="Repair">Repair</String>
<String Id="Uninstalling">Removing</String>
<String Id="Uninstallation">Uninstall</String>
<String Id="ElevateForCRTInstall">You will be prompted for Administrator privileges to install a C Runtime Library update (KB2999226).
Continue?</String>
<String Id="CancelButton">&amp;Cancel</String>
<String Id="CloseButton">&amp;Close</String>
<String Id="InstallHeader">Install [WixBundleName]</String>
<String Id="InstallMessage">Select Install Now to install Python with default settings, or choose Customize to enable or disable features.</String>
<String Id="InstallVersion">Version [WixBundleVersion]</String>
<String Id="InstallUpgradeHeader">Upgrade to [WixBundleName]</String>
<String Id="InstallUpgradeMessage">Select Upgrade Now to keep your current settings, or choose Customize to enable or disable features.</String>
<String Id="ConfirmCancelMessage">Are you sure you want to cancel?</String>
<String Id="ExecuteUpgradeRelatedBundleMessage">Previous version</String>
<String Id="HelpHeader">Setup Help</String>
<String Id="HelpText">Visit &lt;a href="http://docs.python.org/[ShortVersion]/using/windows.html"&gt;docs.python.org/[ShortVersion]/using/windows.html&lt;/a&gt; for the full list of options, including the ability to enable and disable specific features.
"/passive" to display progress without requiring user interaction
"/quiet" to install/uninstall without displaying any UI
"/simple" to prevent user customization
"/uninstall" to remove Python (without confirmation)
"/layout [\[]directory[\]]" to pre-download all components
"/log [\[]filename[\]]" to specify log files location</String>
<String Id="InstallLicenseLinkText">[WixBundleName] &lt;a href="#"&gt;license terms&lt;/a&gt;.</String>
<String Id="InstallAcceptCheckbox">I &amp;agree to the license terms and conditions</String>
<String Id="InstallButton">&amp;Install Now</String>
<String Id="InstallButtonNote">[TargetDir]
Includes IDLE, pip and documentation
Creates shortcuts and file associations</String>
<String Id="InstallCustomButton">C&amp;ustomize installation</String>
<String Id="InstallCustomButtonNote">Choose location and features</String>
<String Id="InstallSimpleButton">&amp;Install</String>
<String Id="InstallSimpleButtonNote">Use settings preselected by your administrator
[SimpleInstallDescription]</String>
<String Id="InstallUpgradeButton">Up&amp;grade Now</String>
<String Id="InstallUpgradeButtonNote">[TargetDir]
Replaces your existing installation without changing settings.
Select Customize to review current options.</String>
<String Id="InstallUpgradeCustomButton">C&amp;ustomize installation</String>
<String Id="InstallUpgradeCustomButtonNote">Choose location and features</String>
<String Id="Custom1Header">Optional Features</String>
<String Id="Custom2Header">Advanced Options</String>
<String Id="CustomLocationLabel">Customize install location</String>
<String Id="CustomLocationHelpLabel">You will require write permissions for the selected location.</String>
<String Id="CustomInstallButton">&amp;Install</String>
<String Id="CustomNextButton">&amp;Next</String>
<String Id="CustomBackButton">&amp;Back</String>
<String Id="CustomBrowseButton">B&amp;rowse</String>
<String Id="Include_docLabel">&amp;Documentation</String>
<String Id="Include_docHelpLabel">Installs the Python documentation files.</String>
<String Id="Include_pipLabel">&amp;pip</String>
<String Id="Include_pipHelpLabel">Installs pip, which can download and install other Python packages.</String>
<String Id="Include_tcltkLabel">Tcl/Tk, turtle and &amp;IDLE</String>
<String Id="Include_tcltkHelpLabel">Installs tkinter, turtle and the IDLE development environment.</String>
<String Id="Include_testLabel">Python &amp;test suite</String>
<String Id="Include_testHelpLabel">Installs the standard library test suite.</String>
<String Id="Include_launcherLabel">py &amp;launcher</String>
<String Id="Include_launcherHelp">Installs the global 'py' launcher to make it easier to start Python.</String>
<String Id="Include_launcherRemove">Use Programs and Features to remove the 'py' launcher.</String>
<String Id="Include_launcherUpgrade">Upgrades the global 'py' launcher from the previous version.</String>
<String Id="AssociateFilesLabel">Associate &amp;files with Python (requires the 'py' launcher)</String>
<String Id="ShortcutsLabel">Create shortcuts for installed applications</String>
<String Id="PrependPathLabel">Add Python to &amp;environment variables</String>
<String Id="ShortPrependPathLabel">Add &amp;python.exe to PATH</String>
<String Id="AppendPathLabel">Append Python to &amp;environment variables</String>
<String Id="ShortAppendPathLabel">Append &amp;python.exe to PATH</String>
<String Id="InstallAllUsersLabel">Install Python [ShortVersion] for &amp;all users</String>
<String Id="InstallLauncherAllUsersLabel">for &amp;all users (requires admin privileges)</String>
<String Id="ShortInstallLauncherAllUsersLabel">Use admin privi&amp;leges when installing py.exe</String>
<String Id="ShortInstallLauncherBlockedLabel">Python Launcher is already installed</String>
<String Id="PrecompileLabel">&amp;Precompile standard library</String>
<String Id="Include_symbolsLabel">Download debugging &amp;symbols</String>
<String Id="Include_debugLabel">Download debu&amp;g binaries (requires VS 2017 or later)</String>
<String Id="Include_freethreadedLabel">Download &amp;free-threaded binaries</String>
<String Id="ProgressHeader">[ActionLikeInstallation] Progress</String>
<String Id="ProgressLabel">[ActionLikeInstalling]:</String>
<String Id="OverallProgressPackageText">Initializing...</String>
<String Id="ModifyHeader">Modify Setup</String>
<String Id="ModifyModifyButton">&amp;Modify</String>
<String Id="ModifyButtonNote">Add or remove individual features.</String>
<String Id="ModifyRepairButton">&amp;Repair</String>
<String Id="RepairButtonNote">Ensure all current features are correctly installed.</String>
<String Id="ModifyUninstallButton">&amp;Uninstall</String>
<String Id="UninstallButtonNote">Remove the entire [WixBundleName] installation.</String>
<String Id="SuccessHeader">[ActionLikeInstallation] was successful</String>
<String Id="SuccessLaunchButton">&amp;Launch</String>
<String Id="SuccessRestartText">You may need to restart your computer to finish updating files.</String>
<String Id="SuccessRestartButton">&amp;Restart</String>
<String Id="SuccessInstallMessage">New to Python? Start with the &lt;a href="https://docs.python.org/[ShortVersion]/tutorial/index.html"&gt;online tutorial&lt;/a&gt; and &lt;a href="https://docs.python.org/[ShortVersion]/index.html"&gt;documentation&lt;/a&gt;. At your terminal, type "py" to launch Python, or search for Python in your Start menu.
See &lt;a href="https://docs.python.org/[ShortVersion]/whatsnew/[ShortVersion].html"&gt;what's new&lt;/a&gt; in this release, or find more info about &lt;a href="https://docs.python.org/[ShortVersion]/using/windows.html"&gt;using Python on Windows&lt;/a&gt;.</String>
<String Id="SuccessModifyMessage">Thank you for using [WixBundleName].</String>
<String Id="SuccessRepairMessage">Thank you for using [WixBundleName].
Feel free to post at &lt;a href="https://discuss.python.org/c/users/7"&gt;discuss.python.org&lt;/a&gt; if you continue to encounter issues.</String>
<String Id="SuccessRemoveMessage">Thank you for using [WixBundleName].
Feel free to post at &lt;a href="https://discuss.python.org/c/users/7"&gt;discuss.python.org&lt;/a&gt; if you encountered problems.</String>
<String Id="FailureHeader">Setup failed</String>
<String Id="FailureHyperlinkLogText">One or more issues caused the setup to fail. Please fix the issues and then retry setup. For more information see the &lt;a href="#"&gt;log file&lt;/a&gt;.</String>
<String Id="FailureRestartText">You must restart your computer to complete the rollback of the software.</String>
<String Id="FailureRestartButton">&amp;Restart</String>
<String Id="FailureExistingInstall">Unable to install [WixBundleName] due to an existing install. Use Programs and Features to modify, repair or remove [WixBundleName].</String>
<String Id="FailureOldOS">At least Windows 10 or Windows Server 2016 are required to install [WixBundleName]
Visit &lt;a href="https://www.python.org/downloads/"&gt;python.org&lt;/a&gt; to download an earlier version of Python.</String>
<String Id="SuccessMaxPathButton">Disable path length limit</String>
<String Id="SuccessMaxPathButtonNote">Changes your machine configuration to allow programs, including Python, to bypass the 260 character "MAX_PATH" limitation.</String>
<String Id="DeprecationMessage">NOTE: This installer is being retired and will no longer be available after Python 3.15. &lt;a href="https://docs.python.org/using/windows"&gt;More info&lt;/a&gt;</String>
</WixLocalization>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

-25
View File
@@ -1,25 +0,0 @@
This license applies to the bootstrapper application that is embedded within the installer. It has no impact on the licensing for the rest of the installer or Python itself, as no code covered by this license exists in any other part of the product.
---
Microsoft Reciprocal License (MS-RL)
This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software.
1. Definitions
The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law.
A "contribution" is the original software, or any additions or changes to the software.
A "contributor" is any person that distributes its contribution under this license.
"Licensed patents" are a contributor's patent claims that read directly on its contribution.
2. Grant of Rights
(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
3. Conditions and Limitations
(A) Reciprocal Grants- For any file you distribute that contains code from the software (in source code or binary format), you must provide recipients the source code to that file along with a copy of this license, which license will govern that file. You may license other files that are entirely your own work and do not contain code from the software under any terms you choose.
(B) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
(C) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
(D) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
(E) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
(F) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
File diff suppressed because it is too large. Load diff
-1
View File
@@ -1 +0,0 @@
#include "pch.h"
-60
View File
@@ -1,60 +0,0 @@
//-------------------------------------------------------------------------------------------------
// <copyright file="precomp.h" company="Outercurve Foundation">
// Copyright (c) 2004, Outercurve Foundation.
// This software is released under Microsoft Reciprocal License (MS-RL).
// The license and further copyright text can be found in the file
// LICENSE.TXT at the root directory of the distribution.
// </copyright>
//
// <summary>
// Precompiled header for standard bootstrapper application.
// </summary>
//-------------------------------------------------------------------------------------------------
#pragma once
#include <windows.h>
#include <gdiplus.h>
#include <uxtheme.h>
#include <msiquery.h>
#include <objbase.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <stdlib.h>
#include <strsafe.h>
#include <stddef.h>
#include <versionhelpers.h>
#include "dutil.h"
#include "memutil.h"
#include "dictutil.h"
#include "dirutil.h"
#include "fileutil.h"
#include "locutil.h"
#include "logutil.h"
#include "pathutil.h"
#include "resrutil.h"
#include "shelutil.h"
#include "strutil.h"
#include "thmutil.h"
#include "uriutil.h"
#include "xmlutil.h"
#include "IBootstrapperEngine.h"
#include "IBootstrapperApplication.h"
#include "BalBaseBootstrapperApplication.h"
#include "balinfo.h"
#include "balcondition.h"
HRESULT CreateBootstrapperApplication(
__in HMODULE hModule,
__in BOOL fPrereq,
__in HRESULT hrHostInitialization,
__in IBootstrapperEngine* pEngine,
__in const BOOTSTRAPPER_COMMAND* pCommand,
__out IBootstrapperApplication** ppApplication
);
#include "IBootstrapperBAFunction.h"
-76
View File
@@ -1,76 +0,0 @@
//-------------------------------------------------------------------------------------------------
// <copyright file="wixstdba.cpp" company="Outercurve Foundation">
// Copyright (c) 2004, Outercurve Foundation.
// This software is released under Microsoft Reciprocal License (MS-RL).
// The license and further copyright text can be found in the file
// LICENSE.TXT at the root directory of the distribution.
// </copyright>
//
// <summary>
// Setup chainer/bootstrapper standard UI for WiX toolset.
// </summary>
//-------------------------------------------------------------------------------------------------
#include "pch.h"
static HINSTANCE vhInstance = NULL;
extern "C" BOOL WINAPI DllMain(
IN HINSTANCE hInstance,
IN DWORD dwReason,
IN LPVOID /* pvReserved */
)
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
::DisableThreadLibraryCalls(hInstance);
vhInstance = hInstance;
break;
case DLL_PROCESS_DETACH:
vhInstance = NULL;
break;
}
return TRUE;
}
extern "C" HRESULT WINAPI BootstrapperApplicationCreate(
__in IBootstrapperEngine* pEngine,
__in const BOOTSTRAPPER_COMMAND* pCommand,
__out IBootstrapperApplication** ppApplication
)
{
HRESULT hr = S_OK;
BalInitialize(pEngine);
hr = CreateBootstrapperApplication(vhInstance, FALSE, S_OK, pEngine, pCommand, ppApplication);
BalExitOnFailure(hr, "Failed to create bootstrapper application interface.");
LExit:
return hr;
}
extern "C" void WINAPI BootstrapperApplicationDestroy()
{
BalUninitialize();
}
extern "C" HRESULT WINAPI MbaPrereqBootstrapperApplicationCreate(
__in HRESULT hrHostInitialization,
__in IBootstrapperEngine* pEngine,
__in const BOOTSTRAPPER_COMMAND* pCommand,
__out IBootstrapperApplication** ppApplication
)
{
return E_NOTIMPL;
}
extern "C" void WINAPI MbaPrereqBootstrapperApplicationDestroy()
{ }
-18
View File
@@ -1,18 +0,0 @@
;-------------------------------------------------------------------------------------------------
; <copyright file="wixstdba.def" company="Outercurve Foundation">
; Copyright (c) 2004, Outercurve Foundation.
; This software is released under Microsoft Reciprocal License (MS-RL).
; The license and further copyright text can be found in the file
; LICENSE.TXT at the root directory of the distribution.
; </copyright>
;
; <summary>
; WiX Standard Bootstrapper Application DLL entry points.
; </summary>
;-------------------------------------------------------------------------------------------------
EXPORTS
BootstrapperApplicationCreate
BootstrapperApplicationDestroy
MbaPrereqBootstrapperApplicationCreate
MbaPrereqBootstrapperApplicationDestroy
-22
View File
@@ -1,22 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.30501.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythonba", "pythonba.vcxproj", "{7A09B132-B3EE-499B-A700-A4B2157FEA3D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7A09B132-B3EE-499B-A700-A4B2157FEA3D}.Debug|Win32.ActiveCfg = Debug|Win32
{7A09B132-B3EE-499B-A700-A4B2157FEA3D}.Debug|Win32.Build.0 = Debug|Win32
{7A09B132-B3EE-499B-A700-A4B2157FEA3D}.Release|Win32.ActiveCfg = Release|Win32
{7A09B132-B3EE-499B-A700-A4B2157FEA3D}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
@@ -1,73 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<copyright file="wixstdba.vcxproj" company="Outercurve Foundation">
Copyright (c) 2004, Outercurve Foundation.
This software is released under Microsoft Reciprocal License (MS-RL).
The license and further copyright text can be found in the file
LICENSE.TXT at the root directory of the distribution.
</copyright>
-->
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<Configuration Condition="'$(Configuration)' == ''">Release</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
<PlatformToolset Condition="'$(PlatformToolset)' == '' and '$(VisualStudioVersion)' == '18.0'">v145</PlatformToolset>
<PlatformToolset Condition="'$(PlatformToolset)' == '' and '$(VisualStudioVersion)' == '17.0'">v143</PlatformToolset>
<PlatformToolset Condition="'$(PlatformToolset)' == '' and '$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
<PlatformToolset Condition="'$(PlatformToolset)' == '' and ('$(MSBuildToolsVersion)' == '15.0' or '$(VisualStudioVersion)' == '15.0')">v141</PlatformToolset>
<ProjectGuid>{7A09B132-B3EE-499B-A700-A4B2157FEA3D}</ProjectGuid>
<TargetName>PythonBA</TargetName>
</PropertyGroup>
<Import Project="..\..\wix.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<Py_IntDir Condition="'$(Py_IntDir)' == ''">$(PySourcePath)PCbuild\obj\</Py_IntDir>
<IntDir>$(Py_IntDir)\$(MajorVersionNumber)$(MinorVersionNumber)$(ArchName)_$(Configuration)\msi_$(ProjectName)\</IntDir>
<IntDir>$(IntDir.Replace(`\\`, `\`))</IntDir>
<OutDir>$(IntDir)</OutDir>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions Condition="$(BuildForPlatform) == 'ARM64'">ARM64=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_CRT_STDIO_LEGACY_WIDE_SPECIFIERS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(WixInstallPath)sdk\inc</AdditionalIncludeDirectories>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<AdditionalDependencies>comctl32.lib;gdiplus.lib;msimg32.lib;shlwapi.lib;wininet.lib;dutil.lib;balutil.lib;version.lib;uxtheme.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories Condition="$(PlatformToolset.StartsWith(`v14`))">$(WixInstallPath)sdk\vs2017\lib\x86</AdditionalLibraryDirectories>
<ModuleDefinitionFile>pythonba.def</ModuleDefinitionFile>
<GenerateDebugInformation Condition="'$(Configuration)'=='Debug'">true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="PythonBootstrapperApplication.cpp" />
<ClCompile Include="pythonba.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<None Include="pythonba.def" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
-25
View File
@@ -1,25 +0,0 @@
//-------------------------------------------------------------------------------------------------
// <copyright file="resource.h" company="Outercurve Foundation">
// Copyright (c) 2004, Outercurve Foundation.
// This software is released under Microsoft Reciprocal License (MS-RL).
// The license and further copyright text can be found in the file
// LICENSE.TXT at the root directory of the distribution.
// </copyright>
//-------------------------------------------------------------------------------------------------
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
//
#define IDC_STATIC -1
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1003
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
-129
View File
@@ -1,129 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" TreatAsLocalProperty="DownloadUrl">
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
<OutputType>Bundle</OutputType>
<BootstrapConfiguration Condition="'$(BootstrapConfiguration)' == ''">Release</BootstrapConfiguration>
<LinkerSuppressSpecificWarnings>1132;1135;1140</LinkerSuppressSpecificWarnings>
<OutputName Condition="$(BuildForRelease)">$(OutputName)-$(PythonVersion)</OutputName>
<OutputName Condition="!$(BuildForRelease)">$(OutputName)-$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber).$(RevisionNumber)</OutputName>
<OutputName Condition="$(Platform) == 'x64'">$(OutputName)-amd64</OutputName>
<OutputName Condition="$(Platform) == 'ARM64'">$(OutputName)-arm64</OutputName>
<OutputName Condition="'$(OutputSuffix)' != ''">$(OutputName)-$(OutputSuffix)</OutputName>
<OutputName Condition="'$(Configuration)' == 'Debug'">$(OutputName)-d</OutputName>
<TargetName>$(OutputName)</TargetName>
<OutputPath>$(OutputPath)en-us\</OutputPath>
<OutDir>$(OutputPath)</OutDir>
<!-- See Tools/msi/buildrelease.bat for help on configuring the download URL -->
<DownloadUrl Condition="'$(DownloadUrl)' == '' and '$(DownloadUrlBase)' != ''">$(DownloadUrlBase.TrimEnd(`/`))/{version}/{arch}{releasename}/{msi}</DownloadUrl>
<DefineConstants Condition="'$(DownloadUrl)' != ''">$(DefineConstants);DownloadUrl=$(DownloadUrl.Replace(`{version}`, `$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)`).Replace(`{arch}`, `$(ArchName)`).Replace(`{releasename}`, `$(ReleaseLevelName)`).Replace(`{msi}`, `{2}`))</DefineConstants>
<DefineConstants Condition="'$(DownloadUrl)' == ''">$(DefineConstants);DownloadUrl={2}</DefineConstants>
</PropertyGroup>
<ItemGroup>
<WixExtension Include="WixUtilExtension">
<HintPath>WixUtilExtension</HintPath>
<Name>WixUtilExtension</Name>
</WixExtension>
<WixExtension Include="WixDependencyExtension">
<HintPath>WixDependencyExtension</HintPath>
<Name>WixDependencyExtension</Name>
</WixExtension>
<WixExtension Include="WixBalExtension">
<HintPath>WixBalExtension</HintPath>
<Name>WixBalExtension</Name>
</WixExtension>
</ItemGroup>
<ItemGroup>
<Compile Include="bundle.wxs" />
<Compile Include="packagegroups\*.wxs" />
</ItemGroup>
<ItemGroup>
<Content Include="Default.thm" />
<Content Include="SideBar.png" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="bundle.wxl" />
<WxlTemplate Include="*_en-US.wxl_template" />
</ItemGroup>
<ItemGroup>
<LinkerBindInputPaths Include="$(OutputPath)">
<BindName></BindName>
</LinkerBindInputPaths>
</ItemGroup>
<ItemDefinitionGroup>
<Package>
<Properties>BuildForRelease=$(BuildForRelease)</Properties>
</Package>
</ItemDefinitionGroup>
<ItemGroup>
<Package Include="..\core\core*.wixproj" />
<Package Include="..\dev\dev*.wixproj" />
<Package Include="..\doc\doc*.wixproj" />
<Package Include="..\exe\exe*.wixproj" />
<Package Include="..\lib\lib*.wixproj" />
<Package Include="..\path\path*.wixproj" />
<Package Include="..\appendpath\appendpath*.wixproj" />
<Package Include="..\pip\pip*.wixproj" />
<Package Include="..\tcltk\tcltk*.wixproj" />
<Package Include="..\test\test*.wixproj" />
<Package Include="..\ucrt\ucrt*.wixproj" Condition="$(Platform) != 'ARM64'" />
<Package Include="..\freethreaded\freethreaded*.wixproj" Condition="$(IncludeFreethreaded) == 'true'" />
</ItemGroup>
<PropertyGroup>
<BuildPackagesTargets>Build</BuildPackagesTargets>
</PropertyGroup>
<Target Name="_SetRebuildTarget" BeforeTargets="BeforeRebuild">
<PropertyGroup>
<BuildPackagesTargets>Rebuild</BuildPackagesTargets>
</PropertyGroup>
</Target>
<Target Name="BuildPackages" BeforeTargets="BeforeBuild" Condition="'$(RebuildAll)' != 'false'">
<MSBuild Projects="@(Package)" Targets="$(BuildPackagesTargets)" BuildInParallel="true" />
</Target>
<Target Name="BuildBootstrapApplication" BeforeTargets="BeforeBuild">
<Message Text="Building bootstrap app" Importance="high" />
<MSBuild Projects="bootstrap\pythonba.vcxproj"
Targets="Build;GetNativeTargetPath"
UseResultsCache="true"
Properties="Configuration=$(BootstrapConfiguration);Platform=Win32;BuildForPlatform=$(Platform)">
<Output TaskParameter="TargetOutputs" PropertyName="BootstrapAppPath" />
</MSBuild>
<PropertyGroup>
<DefineConstants>$(DefineConstants);BootstrapApp=$(BootstrapAppPath)</DefineConstants>
</PropertyGroup>
</Target>
<Target Name="AddDefaultWxl" AfterTargets="PrepareForBuild" Condition="!Exists('Default.$(Platform).xsl')">
<ItemGroup>
<EmbeddedResource Include="Default.wxl" />
</ItemGroup>
<PropertyGroup>
<DefineConstants>$(DefineConstants);DefaultWxl=Default.wxl</DefineConstants>
</PropertyGroup>
</Target>
<Target Name="AddUpdatedDefaultWxl" AfterTargets="PrepareForBuild" Condition="Exists('Default.$(Platform).xsl')">
<XslTransformation XmlInputPaths="Default.wxl"
OutputPaths="$(IntermediateOutputPath)Default.wxl"
XslInputPath="Default.$(Platform).xsl"
UseTrustedSettings="true" />
<ItemGroup>
<EmbeddedResource Include="$(IntermediateOutputPath)Default.wxl" />
</ItemGroup>
<PropertyGroup>
<DefineConstants>$(DefineConstants);DefaultWxl=$(IntermediateOutputPath)Default.wxl</DefineConstants>
</PropertyGroup>
</Target>
<Import Project="..\msi.targets" />
</Project>
-7
View File
@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
<String Id="CRTDescription">C Runtime Update (KB2999226)</String>
<String Id="CompileAllDescription">Precompiling standard library</String>
<String Id="CompileAllODescription">Precompiling standard library (-O)</String>
<String Id="CompileAllOODescription">Precompiling standard library (-OO)</String>
</WixLocalization>
-128
View File
@@ -1,128 +0,0 @@
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"
xmlns:dep="http://schemas.microsoft.com/wix/DependencyExtension">
<Bundle Name="!(loc.FullProductName)"
UpgradeCode="$(var.CoreUpgradeCode)"
Version="$(var.Version)"
IconSourceFile="..\..\..\PC\icons\setup.ico"
Manufacturer="!(loc.Manufacturer)"
AboutUrl="https://www.python.org/"
Compressed="no"
dep:ProviderKey="CPython-$(var.MajorVersionNumber).$(var.MinorVersionNumber)$(var.PyArchExt)$(var.PyTestExt)">
<BootstrapperApplication Id="PythonBA" SourceFile="$(var.BootstrapApp)">
<Payload Compressed='yes' SourceFile='Default.thm' />
<Payload Compressed='yes' SourceFile='$(var.DefaultWxl)' />
<Payload Compressed='yes' SourceFile='SideBar.png' />
</BootstrapperApplication>
<!-- May be set to "Removing" or "Repairing" -->
<Variable Name="ActionLikeInstalling" Value="Installing" />
<!-- May be set to "Uninstallation" or "Repair" -->
<Variable Name="ActionLikeInstallation" Value="Setup" />
<Variable Name="ShortVersion" Value="$(var.MajorVersionNumber).$(var.MinorVersionNumber)" />
<Variable Name="ShortVersionNoDot" Value="$(var.MajorVersionNumber)$(var.MinorVersionNumber)" />
<Variable Name="WinVer" Value="$(var.MajorVersionNumber).$(var.MinorVersionNumber)$(var.PyArchExt)$(var.PyTestExt)" />
<Variable Name="WinVerNoDot" Value="$(var.MajorVersionNumber)$(var.MinorVersionNumber)$(var.PyArchExt)$(var.PyTestExt)" />
<Variable Name="InstallAllUsers" Value="0" bal:Overridable="yes" />
<?if "$(var.PyTestExt)"="" ?>
<Variable Name="InstallLauncherAllUsers" Value="-1" bal:Overridable="yes" />
<?else ?>
<Variable Name="InstallLauncherAllUsers" Value="-1" />
<?endif ?>
<Variable Name="TargetDir" Value="" bal:Overridable="yes" />
<?if $(var.Platform)~="x64" ?>
<Variable Name="DefaultAllUsersTargetDir" Value="[ProgramFiles64Folder]Python[WinVerNoDot]" bal:Overridable="yes" />
<Variable Name="TargetPlatform" Value="x64" />
<?elseif $(var.Platform)~="ARM64" ?>
<Variable Name="DefaultAllUsersTargetDir" Value="[ProgramFiles64Folder]Python[WinVerNoDot]" bal:Overridable="yes" />
<Variable Name="TargetPlatform" Value="ARM64" />
<?else ?>
<Variable Name="DefaultAllUsersTargetDir" Value="[ProgramFilesFolder]Python[WinVerNoDot]" bal:Overridable="yes" />
<Variable Name="TargetPlatform" Value="x86" />
<?endif ?>
<Variable Name="DefaultJustForMeTargetDir" Value="[LocalAppDataFolder]Programs\Python\Python[WinVerNoDot]" bal:Overridable="yes" />
<Variable Name="OptionalFeaturesRegistryKey" Value="Software\Python\PythonCore\[WinVer]\InstalledFeatures" />
<Variable Name="TargetDirRegistryKey" Value="Software\Python\PythonCore\[WinVer]\InstallPath" />
<!--
An empty string will use the other defaults based on InstallAllUsers
(and switch dynamically in the UI). To get the old default, pass
this property on the command line:
DefaultCustomTargetDir=[WindowsVolume]Python[ShortVersionNoDot]
-->
<Variable Name="DefaultCustomTargetDir" Value="" bal:Overridable="yes" />
<Variable Name="InstallAllUsersState" Value="enabled" bal:Overridable="yes" />
<?if "$(var.PyTestExt)"="" ?>
<Variable Name="InstallLauncherAllUsersState" Value="enabled" bal:Overridable="yes" />
<?else ?>
<Variable Name="InstallLauncherAllUsersState" Value="disable" bal:Overridable="yes" />
<?endif ?>
<Variable Name="CustomInstallLauncherAllUsersState" Value="[InstallLauncherAllUsersState]" />
<Variable Name="TargetDirState" Value="enabled" />
<Variable Name="CustomBrowseButtonState" Value="enabled" />
<Variable Name="Include_core" Value="1" />
<Variable Name="Include_exe" Value="1" bal:Overridable="yes" />
<Variable Name="Include_dev" Value="1" bal:Overridable="yes" />
<Variable Name="Include_lib" Value="1" bal:Overridable="yes" />
<Variable Name="Include_test" Value="1" bal:Overridable="yes" />
<Variable Name="Include_doc" Value="1" bal:Overridable="yes" />
<Variable Name="Include_tools" Value="0" bal:Overridable="yes" />
<Variable Name="Include_tcltk" Value="1" bal:Overridable="yes" />
<Variable Name="Include_pip" Value="1" bal:Overridable="yes" />
<Variable Name="Include_launcher" Value="-1" bal:Overridable="yes" />
<?if "$(var.PyTestExt)"="" ?>
<Variable Name="Include_launcherState" Value="enabled" bal:Overridable="yes" />
<?else ?>
<Variable Name="Include_launcherState" Value="disable" />
<?endif ?>
<Variable Name="Include_symbols" Value="0" bal:Overridable="yes" />
<Variable Name="Include_debug" Value="0" bal:Overridable="yes" />
<?if $(var.IncludeFreethreaded)~="true" ?>
<Variable Name="Include_freethreaded" Value="0" bal:Overridable="yes" />
<Variable Name="Include_freethreadedState" Value="enabled" />
<?else ?>
<Variable Name="Include_freethreaded" Value="0" />
<Variable Name="Include_freethreadedState" Value="disable" />
<?endif ?>
<Variable Name="LauncherOnly" Value="0" bal:Overridable="yes" />
<Variable Name="BlockedLauncher" Value="0" />
<Variable Name="DetectedLauncher" Value="0" />
<Variable Name="DetectedOldLauncher" Value="0" />
<Variable Name="AssociateFiles" Value="-1" bal:Overridable="yes" />
<Variable Name="Shortcuts" Value="1" bal:Overridable="yes" />
<Variable Name="PrependPath" Value="0" bal:Overridable="yes" />
<Variable Name="AppendPath" Value="0" bal:Overridable="yes" />
<Variable Name="CompileAll" Value="0" bal:Overridable="yes" />
<Variable Name="SimpleInstall" Value="0" bal:Overridable="yes" />
<Variable Name="SimpleInstallDescription" Value="" bal:Overridable="yes" />
<Chain ParallelCache="yes">
<PackageGroupRef Id="core" />
<PackageGroupRef Id="exe" />
<?if $(var.Platform)!="ARM64" ?>
<PackageGroupRef Id="crt" />
<?endif ?>
<PackageGroupRef Id="dev" />
<PackageGroupRef Id="lib" />
<?if $(var.IncludeFreethreaded)~="true" ?>
<PackageGroupRef Id="freethreaded" />
<?endif ?>
<PackageGroupRef Id="test" />
<PackageGroupRef Id="doc" />
<PackageGroupRef Id="tcltk" />
<PackageGroupRef Id="launcher" />
<PackageGroupRef Id="pip" />
<PackageGroupRef Id="packageinstall" />
<PackageGroupRef Id="postinstall" />
</Chain>
</Bundle>
</Wix>
-21
View File
@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{3E204ADD-238D-4D10-852C-4F859325C839}</ProjectGuid>
<OutputName>python</OutputName>
<OutputSuffix>full</OutputSuffix>
</PropertyGroup>
<Import Project="..\msi.props" />
<PropertyGroup>
<DefineConstants>
$(DefineConstants);
CompressMSI=yes;
CompressPDB=yes;
CompressMSI_D=yes;
</DefineConstants>
</PropertyGroup>
<Import Project="bundle.targets" />
</Project>
-62
View File
@@ -1,62 +0,0 @@
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<PackageGroup Id="core">
<MsiPackage Id="core_AllUsers"
SourceFile="core.msi"
Compressed="$(var.CompressMSI)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="yes"
InstallCondition="InstallAllUsers and (Include_core or Include_exe or Include_launcher or Include_pip) and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="core_AllUsers_pdb"
SourceFile="core_pdb.msi"
Compressed="$(var.CompressPDB)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="yes"
InstallCondition="InstallAllUsers and (Include_core or Include_exe or Include_launcher or Include_pip) and Include_symbols and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="core_AllUsers_d"
SourceFile="core_d.msi"
Compressed="$(var.CompressMSI_D)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="yes"
InstallCondition="InstallAllUsers and (Include_core or Include_exe or Include_launcher or Include_pip) and Include_debug and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="core_JustForMe"
SourceFile="core.msi"
Compressed="$(var.CompressMSI)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="no"
InstallCondition="not InstallAllUsers and (Include_core or Include_exe or Include_launcher or Include_pip) and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="core_JustForMe_pdb"
SourceFile="core_pdb.msi"
Compressed="$(var.CompressPDB)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="no"
InstallCondition="not InstallAllUsers and (Include_core or Include_exe or Include_launcher or Include_pip) and Include_symbols and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="core_JustForMe_d"
SourceFile="core_d.msi"
Compressed="$(var.CompressMSI_D)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="no"
InstallCondition="not InstallAllUsers and (Include_core or Include_exe or Include_launcher or Include_pip) and Include_debug and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
</PackageGroup>
</Fragment>
</Wix>
-23
View File
@@ -1,23 +0,0 @@
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<PackageGroup Id="crt">
<MsiPackage Id="ucrt_AllUsers"
SourceFile="ucrt.msi"
Compressed="no"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="yes"
InstallCondition="InstallAllUsers and not CRTInstalled and (Include_core or Include_exe or Include_pip) and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
</MsiPackage>
<MsiPackage Id="ucrt_JustForMe"
SourceFile="ucrt.msi"
Compressed="no"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="no"
InstallCondition="not InstallAllUsers and not CRTInstalled and (Include_core or Include_exe or Include_pip) and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
</MsiPackage>
</PackageGroup>
</Fragment>
</Wix>
-44
View File
@@ -1,44 +0,0 @@
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<PackageGroup Id="dev">
<MsiPackage Id="dev_AllUsers"
SourceFile="dev.msi"
Compressed="$(var.CompressMSI)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="yes"
InstallCondition="InstallAllUsers and Include_dev and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="dev_AllUsers_d"
SourceFile="dev_d.msi"
Compressed="$(var.CompressMSI_D)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="yes"
InstallCondition="InstallAllUsers and Include_dev and Include_debug and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="dev_JustForMe"
SourceFile="dev.msi"
Compressed="$(var.CompressMSI)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="no"
InstallCondition="not InstallAllUsers and Include_dev and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="dev_JustForMe_d"
SourceFile="dev_d.msi"
Compressed="$(var.CompressMSI_D)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="no"
InstallCondition="not InstallAllUsers and Include_dev and Include_debug and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
</PackageGroup>
</Fragment>
</Wix>
-28
View File
@@ -1,28 +0,0 @@
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<PackageGroup Id="doc">
<MsiPackage Id="doc_AllUsers"
SourceFile="doc.msi"
Compressed="$(var.CompressMSI)"
DownloadUrl="$(var.DownloadUrl)"
EnableFeatureSelection="yes"
ForcePerMachine="yes"
InstallCondition="InstallAllUsers and Include_doc and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="doc_JustForMe"
SourceFile="doc.msi"
Compressed="$(var.CompressMSI)"
DownloadUrl="$(var.DownloadUrl)"
EnableFeatureSelection="yes"
ForcePerMachine="no"
InstallCondition="not InstallAllUsers and Include_doc and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
</PackageGroup>
</Fragment>
</Wix>
-64
View File
@@ -1,64 +0,0 @@
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<PackageGroup Id="exe">
<MsiPackage Id="exe_AllUsers"
SourceFile="exe.msi"
ForcePerMachine="yes"
Compressed="$(var.CompressMSI)"
DownloadUrl="$(var.DownloadUrl)"
EnableFeatureSelection="yes"
InstallCondition="InstallAllUsers and (Include_exe or Include_launcher or Include_pip) and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="exe_AllUsers_pdb"
SourceFile="exe_pdb.msi"
ForcePerMachine="yes"
Compressed="$(var.CompressPDB)"
DownloadUrl="$(var.DownloadUrl)"
InstallCondition="InstallAllUsers and (Include_exe or Include_launcher or Include_pip) and Include_symbols and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="exe_AllUsers_d"
SourceFile="exe_d.msi"
ForcePerMachine="yes"
Compressed="$(var.CompressMSI_D)"
DownloadUrl="$(var.DownloadUrl)"
InstallCondition="InstallAllUsers and (Include_exe or Include_launcher or Include_pip) and Include_debug and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="exe_JustForMe"
SourceFile="exe.msi"
ForcePerMachine="no"
Compressed="$(var.CompressMSI)"
DownloadUrl="$(var.DownloadUrl)"
EnableFeatureSelection="yes"
InstallCondition="not InstallAllUsers and (Include_exe or Include_launcher or Include_pip) and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="exe_JustForMe_pdb"
SourceFile="exe_pdb.msi"
ForcePerMachine="no"
Compressed="$(var.CompressPDB)"
DownloadUrl="$(var.DownloadUrl)"
InstallCondition="not InstallAllUsers and (Include_exe or Include_launcher or Include_pip) and Include_symbols and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="exe_JustForMe_d"
SourceFile="exe_d.msi"
ForcePerMachine="no"
Compressed="$(var.CompressMSI_D)"
DownloadUrl="$(var.DownloadUrl)"
InstallCondition="not InstallAllUsers and (Include_exe or Include_launcher or Include_pip) and Include_debug and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
</PackageGroup>
</Fragment>
</Wix>
@@ -1,62 +0,0 @@
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<PackageGroup Id="freethreaded">
<MsiPackage Id="freethreaded_AllUsers"
SourceFile="freethreaded.msi"
Compressed="no"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="yes"
InstallCondition="InstallAllUsers and (Include_freethreaded) and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="freethreaded_AllUsers_pdb"
SourceFile="freethreaded_pdb.msi"
Compressed="no"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="yes"
InstallCondition="InstallAllUsers and (Include_freethreaded) and Include_symbols and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="freethreaded_AllUsers_d"
SourceFile="freethreaded_d.msi"
Compressed="no"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="yes"
InstallCondition="InstallAllUsers and (Include_freethreaded) and Include_debug and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="freethreaded_JustForMe"
SourceFile="freethreaded.msi"
Compressed="no"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="no"
InstallCondition="not InstallAllUsers and (Include_freethreaded) and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="freethreaded_JustForMe_pdb"
SourceFile="freethreaded_pdb.msi"
Compressed="no"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="no"
InstallCondition="not InstallAllUsers and (Include_freethreaded) and Include_symbols and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="freethreaded_JustForMe_d"
SourceFile="freethreaded_d.msi"
Compressed="no"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="no"
InstallCondition="not InstallAllUsers and (Include_freethreaded) and Include_debug and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
</PackageGroup>
</Fragment>
</Wix>
@@ -1,35 +0,0 @@
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<PackageGroup Id="launcher">
<!-- The All Users launcher is always the 32-bit version -->
<MsiPackage Id="launcher_AllUsers"
SourceFile="!(bindpath.build32)en-us\launcher.msi"
Compressed="$(var.CompressMSI)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="yes"
EnableFeatureSelection="yes"
Permanent="yes"
Visible="yes"
InstallCondition="(InstallAllUsers or InstallLauncherAllUsers) and Include_launcher and not BlockedLauncher">
<?if $(var.Platform)~="ARM64" ?>
<MsiProperty Name="ARM64_SHELLEXT" Value="1" />
<?endif ?>
</MsiPackage>
<MsiPackage Id="launcher_JustForMe"
SourceFile="!(bindpath.build32)en-us\launcher.msi"
Compressed="$(var.CompressMSI)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="no"
EnableFeatureSelection="yes"
Permanent="yes"
Visible="yes"
InstallCondition="not (InstallAllUsers or InstallLauncherAllUsers) and Include_launcher and not BlockedLauncher">
<?if $(var.Platform)~="ARM64" ?>
<MsiProperty Name="ARM64_SHELLEXT" Value="1" />
<?endif ?>
</MsiPackage>
</PackageGroup>
</Fragment>
</Wix>
-62
View File
@@ -1,62 +0,0 @@
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<PackageGroup Id="lib">
<MsiPackage Id="lib_AllUsers"
SourceFile="lib.msi"
Compressed="$(var.CompressMSI)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="yes"
InstallCondition="InstallAllUsers and Include_lib and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="lib_AllUsers_pdb"
SourceFile="lib_pdb.msi"
Compressed="$(var.CompressPDB)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="yes"
InstallCondition="InstallAllUsers and Include_lib and Include_symbols and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="lib_AllUsers_d"
SourceFile="lib_d.msi"
Compressed="$(var.CompressMSI_D)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="yes"
InstallCondition="InstallAllUsers and Include_lib and Include_debug and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="lib_JustForMe"
SourceFile="lib.msi"
Compressed="$(var.CompressMSI)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="no"
InstallCondition="not InstallAllUsers and Include_lib and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="lib_JustForMe_pdb"
SourceFile="lib_pdb.msi"
Compressed="$(var.CompressPDB)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="no"
InstallCondition="not InstallAllUsers and Include_lib and Include_symbols and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="lib_JustForMe_d"
SourceFile="lib_d.msi"
Compressed="$(var.CompressMSI_D)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="no"
InstallCondition="not InstallAllUsers and Include_lib and Include_debug and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
</PackageGroup>
</Fragment>
</Wix>
@@ -1,26 +0,0 @@
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<PackageGroup Id="packageinstall">
<!--
This is an example of installing a package using pip as part of main install.
For a network-only install, remove the Payload element and change the install
command to specify the package and (optionally) version specifier.
<ExePackage Id="requests"
SourceFile="py.exe"
Compressed="yes"
DisplayName="!(loc.CompileAllDescription)"
InstallCommand='-[WinVer] -m pip install requests-2.7.0-py2.py3-none-any.whl'
UninstallCommand='-[WinVer] -m pip uninstall -y requests'
Vital="no"
InstallCondition="Include_pip and not LauncherOnly">
<Payload SourceFile="requests-2.7.0-py2.py3-none-any.whl"
Compressed="$(var.CompressMSI)"
DownloadUrl="$(var.DownloadUrl)" />
</ExePackage>
-->
</PackageGroup>
</Fragment>
</Wix>
-25
View File
@@ -1,25 +0,0 @@
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<PackageGroup Id="pip">
<MsiPackage Id="pip_AllUsers"
SourceFile="pip.msi"
Compressed="$(var.CompressMSI)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="yes"
InstallCondition="InstallAllUsers and Include_pip and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="pip_JustForMe"
SourceFile="pip.msi"
Compressed="$(var.CompressMSI)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="no"
InstallCondition="not InstallAllUsers and Include_pip and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
</PackageGroup>
</Fragment>
</Wix>
@@ -1,109 +0,0 @@
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<PackageGroup Id="postinstall">
<MsiPackage Id="path_AllUsers"
SourceFile="path.msi"
Compressed="$(var.CompressMSI)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="yes"
InstallCondition="InstallAllUsers and PrependPath and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="path_JustForMe"
SourceFile="path.msi"
Compressed="$(var.CompressMSI)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="no"
InstallCondition="not InstallAllUsers and PrependPath and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="appendpath_AllUsers"
SourceFile="appendpath.msi"
Compressed="$(var.CompressMSI)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="yes"
InstallCondition="InstallAllUsers and AppendPath and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="appendpath_JustForMe"
SourceFile="appendpath.msi"
Compressed="$(var.CompressMSI)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="no"
InstallCondition="not InstallAllUsers and AppendPath and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<?define CompileAllCommand=-E -s -Wi "[TargetDir]\Lib\compileall.py" -f -x "bad_coding|badsyntax|site-packages|py2_|venv\\scripts" "[TargetDir]\Lib"?>
<ExePackage Id="compileall_AllUsers"
SourceFile="py.exe"
Compressed="yes"
DisplayName="!(loc.CompileAllDescription)"
InstallCommand='-[WinVer] $(var.CompileAllCommand)'
RepairCommand='-[WinVer] $(var.CompileAllCommand)'
Permanent="yes"
PerMachine="yes"
Vital="no"
InstallCondition="InstallAllUsers and CompileAll and not LauncherOnly" />
<ExePackage Id="compileallO_AllUsers"
SourceFile="py.exe"
Compressed="yes"
DisplayName="!(loc.CompileAllODescription)"
InstallCommand='-[WinVer] -O $(var.CompileAllCommand)'
RepairCommand='-[WinVer] -O $(var.CompileAllCommand)'
Permanent="yes"
PerMachine="yes"
Vital="no"
InstallCondition="InstallAllUsers and CompileAll and not LauncherOnly" />
<ExePackage Id="compileallOO_AllUsers"
SourceFile="py.exe"
Compressed="yes"
DisplayName="!(loc.CompileAllOODescription)"
InstallCommand='-[WinVer] -OO $(var.CompileAllCommand)'
RepairCommand='-[WinVer] -OO $(var.CompileAllCommand)'
Permanent="yes"
PerMachine="yes"
Vital="no"
InstallCondition="InstallAllUsers and CompileAll and not LauncherOnly" />
<ExePackage Id="compileall_JustForMe"
SourceFile="py.exe"
Compressed="yes"
DisplayName="!(loc.CompileAllDescription)"
InstallCommand='-[WinVer] $(var.CompileAllCommand)'
RepairCommand='-[WinVer] $(var.CompileAllCommand)'
Permanent="yes"
PerMachine="no"
Vital="no"
InstallCondition="not InstallAllUsers and CompileAll and not LauncherOnly" />
<ExePackage Id="compileallO_JustForMe"
SourceFile="py.exe"
Compressed="yes"
DisplayName="!(loc.CompileAllODescription)"
InstallCommand='-[WinVer] -O $(var.CompileAllCommand)'
RepairCommand='-[WinVer] -O $(var.CompileAllCommand)'
Permanent="yes"
PerMachine="no"
Vital="no"
InstallCondition="not InstallAllUsers and CompileAll and not LauncherOnly" />
<ExePackage Id="compileallOO_JustForMe"
SourceFile="py.exe"
Compressed="yes"
DisplayName="!(loc.CompileAllOODescription)"
InstallCommand='-[WinVer] -OO $(var.CompileAllCommand)'
RepairCommand='-[WinVer] -OO $(var.CompileAllCommand)'
Permanent="yes"
PerMachine="no"
Vital="no"
InstallCondition="not InstallAllUsers and CompileAll and not LauncherOnly" />
</PackageGroup>
</Fragment>
</Wix>
-68
View File
@@ -1,68 +0,0 @@
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<PackageGroup Id="tcltk">
<MsiPackage Id="tcltk_AllUsers"
SourceFile="tcltk.msi"
Compressed="$(var.CompressMSI)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="yes"
EnableFeatureSelection="yes"
InstallCondition="InstallAllUsers and Include_tcltk and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="tcltk_AllUsers_pdb"
SourceFile="tcltk_pdb.msi"
Compressed="$(var.CompressPDB)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="yes"
EnableFeatureSelection="yes"
InstallCondition="InstallAllUsers and Include_tcltk and Include_symbols and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="tcltk_AllUsers_d"
SourceFile="tcltk_d.msi"
Compressed="$(var.CompressMSI_D)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="yes"
EnableFeatureSelection="yes"
InstallCondition="InstallAllUsers and Include_tcltk and Include_debug and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="tcltk_JustForMe"
SourceFile="tcltk.msi"
Compressed="$(var.CompressMSI)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="no"
EnableFeatureSelection="yes"
InstallCondition="not InstallAllUsers and Include_tcltk and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="tcltk_JustForMe_pdb"
SourceFile="tcltk_pdb.msi"
Compressed="$(var.CompressPDB)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="no"
EnableFeatureSelection="yes"
InstallCondition="not InstallAllUsers and Include_tcltk and Include_symbols and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="tcltk_JustForMe_d"
SourceFile="tcltk_d.msi"
Compressed="$(var.CompressMSI_D)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="no"
EnableFeatureSelection="yes"
InstallCondition="not InstallAllUsers and Include_tcltk and Include_debug and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
</PackageGroup>
</Fragment>
</Wix>
-62
View File
@@ -1,62 +0,0 @@
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<PackageGroup Id="test">
<MsiPackage Id="test_AllUsers"
SourceFile="test.msi"
Compressed="$(var.CompressMSI)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="yes"
InstallCondition="InstallAllUsers and Include_test and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="test_AllUsers_pdb"
SourceFile="test_pdb.msi"
Compressed="$(var.CompressPDB)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="yes"
InstallCondition="InstallAllUsers and Include_test and Include_symbols and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="test_AllUsers_d"
SourceFile="test_d.msi"
Compressed="$(var.CompressMSI_D)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="yes"
InstallCondition="InstallAllUsers and Include_test and Include_debug and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="test_JustForMe"
SourceFile="test.msi"
Compressed="$(var.CompressMSI)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="no"
InstallCondition="not InstallAllUsers and Include_test and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="test_JustForMe_pdb"
SourceFile="test_pdb.msi"
Compressed="$(var.CompressPDB)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="no"
InstallCondition="not InstallAllUsers and Include_test and Include_symbols and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
<MsiPackage Id="test_JustForMe_d"
SourceFile="test_d.msi"
Compressed="$(var.CompressMSI_D)"
DownloadUrl="$(var.DownloadUrl)"
ForcePerMachine="no"
InstallCondition="not InstallAllUsers and Include_test and Include_debug and not LauncherOnly">
<MsiProperty Name="TARGETDIR" Value="[TargetDir]" />
<MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" />
</MsiPackage>
</PackageGroup>
</Fragment>
</Wix>
-21
View File
@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{FCD43AC9-969F-49A1-8AC5-EDC27599D1EB}</ProjectGuid>
<OutputName>python</OutputName>
<OutputSuffix></OutputSuffix>
</PropertyGroup>
<Import Project="..\msi.props" />
<PropertyGroup>
<DefineConstants>
$(DefineConstants);
CompressMSI=yes;
CompressPDB=no;
CompressMSI_D=no
</DefineConstants>
</PropertyGroup>
<Import Project="bundle.targets" />
</Project>
-21
View File
@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{71CDE213-CB39-4BD9-B89D-BBB878689144}</ProjectGuid>
<OutputName>python</OutputName>
<OutputSuffix>webinstall</OutputSuffix>
</PropertyGroup>
<Import Project="..\msi.props" />
<PropertyGroup>
<DefineConstants>
$(DefineConstants);
CompressMSI=no;
CompressPDB=no;
CompressMSI_D=no
</DefineConstants>
</PropertyGroup>
<Import Project="bundle.targets" />
</Project>
-26
View File
@@ -1,26 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{8A4A1162-4BF9-4FF6-9A98-315F01E44932}</ProjectGuid>
<OutputName>python</OutputName>
<OutputSuffix></OutputSuffix>
</PropertyGroup>
<Import Project="..\msi.props" />
<PropertyGroup>
<DefineConstants Condition="'$(Pack)' != 'true'">
$(DefineConstants);CompressMSI=no;
</DefineConstants>
<DefineConstants Condition="'$(Pack)' == 'true'">
$(DefineConstants);CompressMSI=yes;
</DefineConstants>
<DefineConstants>
$(DefineConstants);
CompressPDB=no;
CompressMSI_D=no;
</DefineConstants>
</PropertyGroup>
<Import Project="bundle.targets" />
</Project>
-138
View File
@@ -1,138 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<Property Id="ROOTREGISTRYKEY" Value="Software\Python\PythonCore" />
</Fragment>
<Fragment>
<Property Id="REGISTRYKEY" Value="Software\Python\PythonCore\$(var.ShortVersion)$(var.PyArchExt)$(var.PyTestExt)" />
</Fragment>
<Fragment>
<Component Id="OptionalFeature" Guid="*" Directory="InstallDirectory">
<Condition>OPTIONALFEATURESREGISTRYKEY</Condition>
<RegistryKey Root="HKMU" Key="[OPTIONALFEATURESREGISTRYKEY]">
<RegistryValue Type="string" Name="$(var.OptionalFeatureName)" Value="$(var.Version)" KeyPath="yes" />
</RegistryKey>
</Component>
</Fragment>
<Fragment>
<Property Id="UpgradeTable" Value="1" />
<?ifndef SuppressUpgradeTable ?>
<Upgrade Id="$(var.UpgradeCode)">
<UpgradeVersion Property="DOWNGRADE" Minimum="$(var.Version)" IncludeMinimum="no" OnlyDetect="yes" />
<UpgradeVersion Property="UPGRADE" Minimum="$(var.UpgradeMinimumVersion)" IncludeMinimum="yes" Maximum="$(var.Version)" IncludeMaximum="no" />
</Upgrade>
<?ifdef CoreUpgradeCode ?>
<?if $(var.UpgradeCode)!=$(var.CoreUpgradeCode) ?>
<Upgrade Id="$(var.CoreUpgradeCode)">
<UpgradeVersion Property="MISSING_CORE" Minimum="$(var.Version)" IncludeMinimum="yes" Maximum="$(var.Version)" IncludeMaximum="yes" OnlyDetect="yes" />
</Upgrade>
<Condition Message="!(loc.IncorrectCore)">Installed OR NOT MISSING_CORE</Condition>
<?endif ?>
<?endif ?>
<Condition Message="!(loc.NoDowngrade)">Installed OR NOT DOWNGRADE</Condition>
<Condition Message="!(loc.NoTargetDir)">Installed OR TARGETDIR OR Suppress_TARGETDIR_Check</Condition>
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallInitialize" Overridable="yes">UPGRADE</RemoveExistingProducts>
</InstallExecuteSequence>
<?endif ?>
</Fragment>
<Fragment>
<!-- Include an icon for the Programs and Features dialog -->
<Icon Id="ARPIcon" SourceFile="!(bindpath.src)PC\icons\python.ico" />
<Property Id="ARPPRODUCTICON" Value="ARPIcon" />
<Property Id="ARPNOMODIFY" Value="1" />
<Property Id="DISABLEADVTSHORTCUTS" Value="1" />
</Fragment>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<?ifdef InstallDirectoryGuidSeed ?>
<Directory Id="InstallDirectory" ComponentGuidGenerationSeed="$(var.InstallDirectoryGuidSeed)" />
<?endif ?>
</Directory>
</Fragment>
<Fragment>
<?ifdef PythonExeComponentGuid ?>
<!-- Locate TARGETDIR automatically assuming we have executables installed -->
<Property Id="TARGETDIR">
<ComponentSearch Id="PythonExe_Directory" Guid="$(var.PythonExeComponentGuid)">
<DirectorySearch Id="PythonExe_Directory" AssignToProperty="yes" Path=".">
<FileSearch Id="PythonExe_DirectoryFile" Name="python.exe" />
</DirectorySearch>
</ComponentSearch>
</Property>
<?endif ?>
<Property Id="DetectTargetDir" Value="1" />
</Fragment>
<!-- Top-level directories -->
<Fragment>
<DirectoryRef Id="InstallDirectory">
<Directory Id="abi3t_compat" Name="abi3t-compat" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="InstallDirectory">
<Directory Id="DLLs" Name="DLLs">
<Directory Id="Catalogs" />
</Directory>
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="InstallDirectory">
<Directory Id="Doc" Name="Doc">
<Directory Id="Doc_html" Name="html" />
</Directory>
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="InstallDirectory">
<Directory Id="include" Name="include" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="InstallDirectory">
<Directory Id="Lib" Name="Lib" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="InstallDirectory">
<Directory Id="libs" Name="libs" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="InstallDirectory">
<Directory Id="Scripts" Name="Scripts" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="InstallDirectory">
<Directory Id="tcl" Name="tcl" />
</DirectoryRef>
</Fragment>
<!-- Start Menu folder -->
<Fragment>
<DirectoryRef Id="TARGETDIR">
<Directory Id="ProgramMenuFolder">
<Directory Id="MenuDir" Name="!(loc.ProductName)" />
</Directory>
</DirectoryRef>
</Fragment>
</Wix>
-18
View File
@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
<String Id="LCID">1033</String>
<String Id="Culture">en-us</String>
<String Id="ProductName">Python {{ShortVersion}}</String>
<String Id="FullProductName">Python {{LongVersion}} ({{Bitness}})</String>
<String Id="Title">Python {{LongVersion}} !(loc.Descriptor) ({{Bitness}})</String>
<String Id="Description">Python {{LongVersion}} !(loc.Descriptor) ({{Bitness}})</String>
<String Id="TitlePdb">Python {{LongVersion}} !(loc.Descriptor) ({{Bitness}} symbols)</String>
<String Id="DescriptionPdb">Python {{LongVersion}} !(loc.Descriptor) ({{Bitness}} symbols)</String>
<String Id="Title_d">Python {{LongVersion}} !(loc.Descriptor) ({{Bitness}} debug)</String>
<String Id="Description_d">Python {{LongVersion}} !(loc.Descriptor) ({{Bitness}} debug)</String>
<String Id="Manufacturer">Python Software Foundation</String>
<String Id="NoDowngrade">A newer version of !(loc.ProductName) is already installed.</String>
<String Id="IncorrectCore">An incorrect version of a prerequisite package is installed. Please uninstall any other versions of !(loc.ProductName) and try installing this again.</String>
<String Id="NoTargetDir">The TARGETDIR variable must be provided when invoking this installer.</String>
<String Id="ManufacturerSupportUrl">https://www.python.org/</String>
</WixLocalization>
-19
View File
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{1B4502D5-B627-4F50-ABEA-4CC5A8E88265}</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion>
<OutputName>core</OutputName>
<OutputType>Package</OutputType>
</PropertyGroup>
<Import Project="..\msi.props" />
<ItemGroup>
<Compile Include="core.wxs" />
<Compile Include="core_files.wxs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="*.wxl" />
</ItemGroup>
<Import Project="..\msi.targets" />
</Project>
-13
View File
@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Language="!(loc.LCID)" Name="!(loc.Title)" Version="$(var.Version)" Manufacturer="!(loc.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
<Package InstallerVersion="500" Compressed="yes" InstallScope="perUser" />
<MediaTemplate EmbedCab="yes" CompressionLevel="high" />
<PropertyRef Id="UpgradeTable" />
<Feature Id="DefaultFeature" AllowAdvertise="no" Title="!(loc.Title)" Description="!(loc.Description)">
<ComponentGroupRef Id="core_dll" />
</Feature>
</Product>
</Wix>
-19
View File
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{D3677DCF-098A-4398-9FA5-8E74AC37E0DF}</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion>
<OutputName>core_d</OutputName>
<OutputType>Package</OutputType>
</PropertyGroup>
<Import Project="..\msi.props" />
<ItemGroup>
<Compile Include="core_d.wxs" />
<Compile Include="core_files.wxs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="*.wxl" />
</ItemGroup>
<Import Project="..\msi.targets" />
</Project>
-14
View File
@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Language="!(loc.LCID)" Name="!(loc.Title_d)" Version="$(var.Version)" Manufacturer="!(loc.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
<Package InstallerVersion="500" Compressed="yes" InstallScope="perUser" />
<MediaTemplate EmbedCab="yes" CompressionLevel="high" />
<PropertyRef Id="UpgradeTable" />
<Feature Id="DebugBinaries" AllowAdvertise="no" Title="!(loc.Title_d)" Description="!(loc.Description_d)">
<ComponentGroupRef Id="core_dll_d" />
<ComponentRef Id="OptionalFeature" />
</Feature>
</Product>
</Wix>
-5
View File
@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
<String Id="Descriptor">Core Interpreter</String>
<String Id="ShortDescriptor">core</String>
</WixLocalization>
-37
View File
@@ -1,37 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<ComponentGroup Id="core_dll">
<Component Id="python_abi3tcompat.dll" Directory="abi3t_compat" Guid="*">
<File Id="python_abi3tcompat.dll" Name="python$(var.MajorVersionNumber)t.dll" KeyPath="yes" />
</Component>
<Component Id="python_stable.dll" Directory="InstallDirectory" Guid="*">
<File Id="python_stable.dll" Name="python$(var.MajorVersionNumber).dll" KeyPath="yes" />
</Component>
<Component Id="python.dll" Directory="InstallDirectory" Guid="*">
<File Id="python.dll" Name="python$(var.MajorVersionNumber)$(var.MinorVersionNumber).dll" KeyPath="yes" />
</Component>
</ComponentGroup>
</Fragment>
<Fragment>
<ComponentGroup Id="core_symbols">
<Component Id="python.pdb" Directory="InstallDirectory" Guid="*">
<File Id="python.pdb" Name="python$(var.MajorVersionNumber)$(var.MinorVersionNumber).pdb" KeyPath="yes" />
</Component>
</ComponentGroup>
</Fragment>
<Fragment>
<ComponentGroup Id="core_dll_d">
<Component Id="python_abi3tcompat_d.dll" Directory="abi3t_compat" Guid="*">
<File Id="python_abi3tcompat_d.dll" Name="python$(var.MajorVersionNumber)t_d.dll" KeyPath="yes" />
</Component>
<Component Id="python_stable_d.dll" Directory="InstallDirectory" Guid="*">
<File Id="python_stable_d.dll" Name="python$(var.MajorVersionNumber)_d.dll" KeyPath="yes" />
</Component>
<Component Id="python_d.dll" Directory="InstallDirectory" Guid="*">
<File Id="python_d.dll" Name="python$(var.MajorVersionNumber)$(var.MinorVersionNumber)_d.dll" KeyPath="yes" />
<File Id="python_d.pdb" Name="python$(var.MajorVersionNumber)$(var.MinorVersionNumber)_d.pdb" KeyPath="no" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>
-19
View File
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{E98E7539-64E7-4DCE-AACD-01E3ADE40EFD}</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion>
<OutputName>core_pdb</OutputName>
<OutputType>Package</OutputType>
</PropertyGroup>
<Import Project="..\msi.props" />
<ItemGroup>
<Compile Include="core_pdb.wxs" />
<Compile Include="core_files.wxs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="*.wxl" />
</ItemGroup>
<Import Project="..\msi.targets" />
</Project>
-14
View File
@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Language="!(loc.LCID)" Name="!(loc.TitlePdb)" Version="$(var.Version)" Manufacturer="!(loc.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
<Package InstallerVersion="500" Compressed="yes" InstallScope="perUser" />
<MediaTemplate EmbedCab="yes" CompressionLevel="high" />
<PropertyRef Id="UpgradeTable" />
<Feature Id="Symbols" AllowAdvertise="no" Title="!(loc.TitlePdb)" Description="!(loc.DescriptionPdb)">
<ComponentGroupRef Id="core_symbols" />
<ComponentRef Id="OptionalFeature" />
</Feature>
</Product>
</Wix>
-127
View File
@@ -1,127 +0,0 @@
'''
Processes a CSV file containing a list of files into a WXS file with
components for each listed file.
The CSV columns are:
source of file, target for file, group name
Usage::
py txt_to_wxs.py [path to file list .csv] [path to destination .wxs]
This is necessary to handle structures where some directories only
contain other directories. MSBuild is not able to generate the
Directory entries in the WXS file correctly, as it operates on files.
Python, however, can easily fill in the gap.
'''
__author__ = "Steve Dower <steve.dower@microsoft.com>"
import csv
import re
import sys
from collections import defaultdict
from itertools import chain, zip_longest
from pathlib import PureWindowsPath
from uuid import uuid1
ID_CHAR_SUBS = {
'-': '_',
'+': '_P',
}
def make_id(path):
return re.sub(
r'[^A-Za-z0-9_.]',
lambda m: ID_CHAR_SUBS.get(m.group(0), '_'),
str(path).rstrip('/\\'),
flags=re.I
)
DIRECTORIES = set()
def main(file_source, install_target):
with open(file_source, 'r', newline='') as f:
files = list(csv.reader(f))
assert len(files) == len(set(make_id(f[1]) for f in files)), "Duplicate file IDs exist"
directories = defaultdict(set)
cache_directories = defaultdict(set)
groups = defaultdict(list)
for source, target, group, disk_id, condition in files:
target = PureWindowsPath(target)
groups[group].append((source, target, disk_id, condition))
if target.suffix.lower() in {".py", ".pyw"}:
cache_directories[group].add(target.parent)
for dirname in target.parents:
parent = make_id(dirname.parent)
if parent and parent != '.':
directories[parent].add(dirname.name)
lines = [
'<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">',
' <Fragment>',
]
for dir_parent in sorted(directories):
lines.append(' <DirectoryRef Id="{}">'.format(dir_parent))
for dir_name in sorted(directories[dir_parent]):
lines.append(' <Directory Id="{}_{}" Name="{}" />'.format(dir_parent, make_id(dir_name), dir_name))
lines.append(' </DirectoryRef>')
for dir_parent in (make_id(d) for group in cache_directories.values() for d in group):
lines.append(' <DirectoryRef Id="{}">'.format(dir_parent))
lines.append(' <Directory Id="{}___pycache__" Name="__pycache__" />'.format(dir_parent))
lines.append(' </DirectoryRef>')
lines.append(' </Fragment>')
for group in sorted(groups):
lines.extend([
' <Fragment>',
' <ComponentGroup Id="{}">'.format(group),
])
for source, target, disk_id, condition in groups[group]:
lines.append(' <Component Id="{}" Directory="{}" Guid="*">'.format(make_id(target), make_id(target.parent)))
if condition:
lines.append(' <Condition>{}</Condition>'.format(condition))
if disk_id:
lines.append(' <File Id="{}" Name="{}" Source="{}" DiskId="{}" />'.format(make_id(target), target.name, source, disk_id))
else:
lines.append(' <File Id="{}" Name="{}" Source="{}" />'.format(make_id(target), target.name, source))
lines.append(' </Component>')
create_folders = {make_id(p) + "___pycache__" for p in cache_directories[group]}
remove_folders = {make_id(p2) for p1 in cache_directories[group] for p2 in chain((p1,), p1.parents)}
create_folders.discard(".")
remove_folders.discard(".")
if create_folders or remove_folders:
lines.append(' <Component Id="{}__pycache__folders" Directory="TARGETDIR" Guid="{}">'.format(group, uuid1()))
lines.extend(' <CreateFolder Directory="{}" />'.format(p) for p in create_folders)
lines.extend(' <RemoveFile Id="Remove_{0}_files" Name="*" On="uninstall" Directory="{0}" />'.format(p) for p in create_folders)
lines.extend(' <RemoveFolder Id="Remove_{0}_folder" On="uninstall" Directory="{0}" />'.format(p) for p in create_folders | remove_folders)
lines.append(' </Component>')
lines.extend([
' </ComponentGroup>',
' </Fragment>',
])
lines.append('</Wix>')
# Check if the file matches. If so, we don't want to touch it so
# that we can skip rebuilding.
try:
with open(install_target, 'r') as f:
if all(x.rstrip('\r\n') == y for x, y in zip_longest(f, lines)):
print('File is up to date')
return
except IOError:
pass
with open(install_target, 'w') as f:
f.writelines(line + '\n' for line in lines)
print('Wrote {} lines to {}'.format(len(lines), install_target))
if __name__ == '__main__':
main(sys.argv[1], sys.argv[2])
-29
View File
@@ -1,29 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{5F23F608-D74B-4259-A0CE-8DC65CC7FE53}</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion>
<OutputName Condition="'$(OutputName)' == ''">dev</OutputName>
<OutputType>Package</OutputType>
</PropertyGroup>
<Import Project="..\msi.props" />
<ItemGroup>
<Compile Include="dev.wxs" />
<Compile Include="dev_files.wxs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="*.wxl" />
</ItemGroup>
<ItemGroup>
<InstallFiles Include="$(PySourcePath)include\**\*.h"
Exclude="$(PySourcePath)include\pyconfig.h">
<SourceBase>$(PySourcePath)</SourceBase>
<Source>!(bindpath.src)</Source>
<TargetBase>$(PySourcePath)</TargetBase>
<Target_></Target_>
<Group>dev_include</Group>
</InstallFiles>
</ItemGroup>
<Import Project="..\msi.targets" />
</Project>
-17
View File
@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Language="!(loc.LCID)" Name="!(loc.Title)" Version="$(var.Version)" Manufacturer="!(loc.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
<Package InstallerVersion="500" Compressed="yes" InstallScope="perUser" />
<MediaTemplate EmbedCab="yes" CompressionLevel="high" />
<PropertyRef Id="DetectTargetDir" />
<PropertyRef Id="UpgradeTable" />
<Feature Id="DefaultFeature" AllowAdvertise="no" Title="!(loc.Title)" Description="!(loc.Description)">
<ComponentGroupRef Id="dev_include" />
<ComponentGroupRef Id="dev_pyconfig" />
<ComponentGroupRef Id="dev_libs" />
<ComponentRef Id="OptionalFeature" />
</Feature>
</Product>
</Wix>
-19
View File
@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{C11B4945-76BD-4137-B2E3-649460117A77}</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion>
<OutputName>dev_d</OutputName>
<OutputType>Package</OutputType>
</PropertyGroup>
<Import Project="..\msi.props" />
<ItemGroup>
<Compile Include="dev_d.wxs" />
<Compile Include="dev_files.wxs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="*.wxl" />
</ItemGroup>
<Import Project="..\msi.targets" />
</Project>
Loaded 100 of 184 files, more files were not shown because too many files have changed in this diff. Show more