mirror of
https://github.com/python/cpython.git
synced 2026-10-28 10:25:05 +08:00
gh-153511: Removes Tools/msi, Tools/nuget, and legacy py.exe launcher sources (GH-153512)
This commit is contained in:
1 parent
c7bbf040e7
commit
bd315837d8
184 files changed
+389
-17781
No files matched your search
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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. |
|
||||
+-------------------+-------+-----------------------------------------------+
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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`.
|
||||
|
||||
|
||||
@@ -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 +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.
@@ -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
|
||||
@@ -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
File diff suppressed because it is too large.
Load diff
-2858
File diff suppressed because it is too large.
Load diff
@@ -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.
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
EXPORTS
|
||||
DllRegisterServer PRIVATE
|
||||
DllUnregisterServer PRIVATE
|
||||
DllGetClassObject PRIVATE
|
||||
DllCanUnloadNow PRIVATE
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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)" />
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
@@ -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,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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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
@@ -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).
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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
@@ -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::
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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">&Cancel</String>
|
||||
<String Id="CloseButton">&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 <a href="http://docs.python.org/[ShortVersion]/using/windows.html">docs.python.org/[ShortVersion]/using/windows.html</a> 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] <a href="#">license terms</a>.</String>
|
||||
<String Id="InstallAcceptCheckbox">I &agree to the license terms and conditions</String>
|
||||
<String Id="InstallButton">&Install Now</String>
|
||||
<String Id="InstallButtonNote">[TargetDir]
|
||||
|
||||
Includes IDLE, pip and documentation
|
||||
Creates shortcuts and file associations</String>
|
||||
<String Id="InstallCustomButton">C&ustomize installation</String>
|
||||
<String Id="InstallCustomButtonNote">Choose location and features</String>
|
||||
<String Id="InstallSimpleButton">&Install</String>
|
||||
<String Id="InstallSimpleButtonNote">Use settings preselected by your administrator
|
||||
|
||||
[SimpleInstallDescription]</String>
|
||||
<String Id="InstallUpgradeButton">Up&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&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">&Install</String>
|
||||
<String Id="CustomNextButton">&Next</String>
|
||||
<String Id="CustomBackButton">&Back</String>
|
||||
<String Id="CustomBrowseButton">B&rowse</String>
|
||||
<String Id="Include_docLabel">&Documentation</String>
|
||||
<String Id="Include_docHelpLabel">Installs the Python documentation files.</String>
|
||||
<String Id="Include_pipLabel">&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 &IDLE</String>
|
||||
<String Id="Include_tcltkHelpLabel">Installs tkinter, turtle and the IDLE development environment.</String>
|
||||
<String Id="Include_testLabel">Python &test suite</String>
|
||||
<String Id="Include_testHelpLabel">Installs the standard library test suite.</String>
|
||||
<String Id="Include_launcherLabel">py &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 &files with Python (requires the 'py' launcher)</String>
|
||||
<String Id="ShortcutsLabel">Create shortcuts for installed applications</String>
|
||||
<String Id="PrependPathLabel">Add Python to &environment variables</String>
|
||||
<String Id="ShortPrependPathLabel">Add &python.exe to PATH</String>
|
||||
<String Id="AppendPathLabel">Append Python to &environment variables</String>
|
||||
<String Id="ShortAppendPathLabel">Append &python.exe to PATH</String>
|
||||
<String Id="InstallAllUsersLabel">Install Python [ShortVersion] for &all users</String>
|
||||
<String Id="InstallLauncherAllUsersLabel">for &all users (requires admin privileges)</String>
|
||||
<String Id="ShortInstallLauncherAllUsersLabel">Use admin privi&leges when installing py.exe</String>
|
||||
<String Id="ShortInstallLauncherBlockedLabel">Python Launcher is already installed</String>
|
||||
<String Id="PrecompileLabel">&Precompile standard library</String>
|
||||
<String Id="Include_symbolsLabel">Download debugging &symbols</String>
|
||||
<String Id="Include_debugLabel">Download debu&g binaries (requires VS 2017 or later)</String>
|
||||
<String Id="Include_freethreadedLabel">Download &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">&Modify</String>
|
||||
<String Id="ModifyButtonNote">Add or remove individual features.</String>
|
||||
<String Id="ModifyRepairButton">&Repair</String>
|
||||
<String Id="RepairButtonNote">Ensure all current features are correctly installed.</String>
|
||||
<String Id="ModifyUninstallButton">&Uninstall</String>
|
||||
<String Id="UninstallButtonNote">Remove the entire [WixBundleName] installation.</String>
|
||||
<String Id="SuccessHeader">[ActionLikeInstallation] was successful</String>
|
||||
<String Id="SuccessLaunchButton">&Launch</String>
|
||||
<String Id="SuccessRestartText">You may need to restart your computer to finish updating files.</String>
|
||||
<String Id="SuccessRestartButton">&Restart</String>
|
||||
<String Id="SuccessInstallMessage">New to Python? Start with the <a href="https://docs.python.org/[ShortVersion]/tutorial/index.html">online tutorial</a> and <a href="https://docs.python.org/[ShortVersion]/index.html">documentation</a>. At your terminal, type "py" to launch Python, or search for Python in your Start menu.
|
||||
|
||||
See <a href="https://docs.python.org/[ShortVersion]/whatsnew/[ShortVersion].html">what's new</a> in this release, or find more info about <a href="https://docs.python.org/[ShortVersion]/using/windows.html">using Python on Windows</a>.</String>
|
||||
<String Id="SuccessModifyMessage">Thank you for using [WixBundleName].</String>
|
||||
<String Id="SuccessRepairMessage">Thank you for using [WixBundleName].
|
||||
|
||||
Feel free to post at <a href="https://discuss.python.org/c/users/7">discuss.python.org</a> if you continue to encounter issues.</String>
|
||||
<String Id="SuccessRemoveMessage">Thank you for using [WixBundleName].
|
||||
|
||||
Feel free to post at <a href="https://discuss.python.org/c/users/7">discuss.python.org</a> 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 <a href="#">log file</a>.</String>
|
||||
<String Id="FailureRestartText">You must restart your computer to complete the rollback of the software.</String>
|
||||
<String Id="FailureRestartButton">&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 <a href="https://www.python.org/downloads/">python.org</a> 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. <a href="https://docs.python.org/using/windows">More info</a></String>
|
||||
</WixLocalization>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 51 KiB |
@@ -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 +0,0 @@
|
||||
#include "pch.h"
|
||||
@@ -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"
|
||||
|
||||
@@ -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()
|
||||
{ }
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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])
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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
Reference in new issue
Block a user