bdist_msi¶
This command is implemented by cx_Freeze to handle installing executables and their dependencies creating Windows installer packages.
For Python 3.13+ cx_Freeze is using python-msilib with support for Windows x64 and also for Windows ARM64.
cxfreeze bdist_msipython setup.py bdist_msi
The following options are available for the command:
- add-to-path¶
add the target directory to the PATH environment variable [default: False]
- all-users¶
install for all users or just for the installing user [default: False]
- data¶
dictionary of arbitrary MSI data indexed by table name; for each table, a list of tuples should be provided, representing the rows that should be added to the table. For binary values (e.g. Icon.Data), pass the path to the file containing the data.
- directories¶
list of directories that should be created during installation.
- environment-variables¶
list of environment variables that should be added to the system during installation.
- extensions¶
list of dictionaries specifying the extensions that the installed program handles. Each extension needs to specify at least the extension, a verb, and an executable. Additional allowed keys are argument to specify the invocation of the executable, mime for the extension’s mime type, and context for the context menu text.
- initial-target-dir¶
defines the initial target directory supplied to the user during installation; to specify a target directory of “XYZ” in the default program directory use “[ProgramFiles64Folder]XYZ” or “[ProgramFilesFolder]XYZ” (for the default 64-bit or non-64-bit locations, respectively).
- install-icon¶
path of icon to use for the add/remove programs window that pops up during installation.
- launch-on-finish¶
boolean flag that includes a “Launch the installed app on finish?” checkbox to the final step of the installer [default: False]
- license-file¶
path to a rtf formmated file to be used as the license agreement; refer to Windows Installer Scrollable Text .
- output-name¶
specifies the name of the file that is to be created [default: metadata name-version-platform.msi]
- product-code¶
define the product code for the package that is created
- product-name¶
define the product name for the package that is created [default: metadata name]
- product-version¶
define the product version for the package that is created [default: metadata version if available]
- summary-data¶
dictionary of data to include in MSI summary information stream (allowable keys are “author”, “comments”, and “keywords”).
- upgrade-code¶
define the GUID of the upgrade code for the package that is created; this is used to force the removal of any packages created with the same upgrade code before the installation of this one; the valid format for a GUID is {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} where X is a hex digit. Refer to Windows GUID .
Added in version 6.7: extensions option.
Added in version 7.2: license-file option.
Added in version 8.2: launch-on-finish option.
Added in version 8.6: output-name, product-name, and
product-version options.
Removed in version 8.6: target-name option.
For example:
[project] name = "hello" version = "0.1.2.3" description = "Sample cx_Freeze script to test MSI arbitrary data stream" [[tool.cxfreeze.executables]] script = "hello.py" base = "gui" copyright = "Copyright (C) 2026 cx_Freeze" icon = "icon.ico" shortcut-name = "My Program Name" shortcut-dir = "MyProgramMenu" [tool.cxfreeze.build_exe] excludes = ["tkinter", "unittest"] include-msvcr = true [tool.cxfreeze.bdist_msi] add-to-path = true environment-variables = [ ["E_MYAPP_VAR", "=-*MYAPP_VAR", "1", "TARGETDIR"] ] product-name = "Hello cx_Freeze" # use a different upgrade-code for your project upgrade-code = "{6B29FC40-CA47-1067-B31D-00DD010662DA}" [tool.cxfreeze.bdist_msi.data] Directory = [ ["ProgramMenuFolder", "TARGETDIR", "."], ["MyProgramMenu", "ProgramMenuFolder", "MYPROG~1|My Program"] ] ProgId = [ ["Prog.Id", 0, 0, "This is a description", "IconId", 0] ] Icon = [ ["IconId", "icon.ico"] ]from cx_Freeze import Executable, setup directory_table = [ ("ProgramMenuFolder", "TARGETDIR", "."), ("MyProgramMenu", "ProgramMenuFolder", "MYPROG~1|My Program"), ] msi_data = { "Directory": directory_table, "ProgId": [ ("Prog.Id", None, None, "This is a description", "IconId", None), ], "Icon": [ ("IconId", "icon.ico"), ], } bdist_msi_options = { "add_to_path": True, "data": msi_data, "environment_variables": [ ("E_MYAPP_VAR", "=-*MYAPP_VAR", "1", "TARGETDIR") ], "upgrade_code": "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}", } build_exe_options = {"excludes": ["tkinter"], "include_msvcr": True} executables = [ Executable( "hello.py", base="gui", copyright="Copyright (C) 2026 cx_Freeze", icon="icon.ico", shortcut_name="My Program Name", shortcut_dir="MyProgramMenu", ) ] setup( name="hello", version="0.1", description="Sample cx_Freeze script to test MSI arbitrary data stream", executables=executables, options={ "build_exe": build_exe_options, "bdist_msi": bdist_msi_options, }, )
Samples: There are more examples in the samples directory.
See also