Repository: beeware/briefcase

Issue:
User installable MSI packages?
The Mu Editor MSI file I managed to produce in the context of #381 requires administrative privileges for installation.

It would be very nice if `briefcase` had the option to produce user installable MSI files (assuming there is such a thing -- I suppose/hope so, given that lots of software is user installable, nowadays). If not, that could be considered a user-experience regression with respect to Mu users...

Which of user-install/system-install should be the default is a secondary thing for now.

Thoughts?

Discussion:

Patch:
diff --git a/changes/382.feature.rst b/changes/382.feature.rst
new file mode 100644
index 00000000..3cc4e55e
--- /dev/null
+++ b/changes/382.feature.rst
@@ -0,0 +1,1 @@
+Windows MSI installers can now be configured to ask the user whether they want a per-user or per-machine install.
diff --git a/changes/688.bugfix.rst b/changes/688.bugfix.rst
new file mode 100644
index 00000000..a7f2db90
--- /dev/null
+++ b/changes/688.bugfix.rst
@@ -0,0 +1,1 @@
+Windows MSI installers now install in ``Program Files``, rather than ``Program Files (x86)``.
diff --git a/docs/reference/platforms/windows/msi.rst b/docs/reference/platforms/windows/msi.rst
index 870611e6..d767d4ae 100644
--- a/docs/reference/platforms/windows/msi.rst
+++ b/docs/reference/platforms/windows/msi.rst
@@ -43,7 +43,8 @@ installer; however, they are installed once and shared between all users on a
 computer.
 
 If ``true`` the installer will attempt to install the app as a per-machine app,
-available to all users. Defaults to a per-user install.
+available to all users. If ``false``, the installer will install as a per-user
+app. If undefined the installer will ask the user for their preference.
 
 ``version_triple``
 ------------------
diff --git a/src/briefcase/platforms/windows/msi.py b/src/briefcase/platforms/windows/msi.py
index 0023f89d..204a48f7 100644
--- a/src/briefcase/platforms/windows/msi.py
+++ b/src/briefcase/platforms/windows/msi.py
@@ -77,13 +77,17 @@ class WindowsMSICreateCommand(WindowsMSIMixin, CreateCommand):
         try:
             install_scope = "perMachine" if app.system_installer else "perUser"
         except AttributeError:
-            # system_installer not defined in config; default to perUser install.
-            install_scope = "perUser"
+            # system_installer not defined in config; default to asking the user
+            install_scope = None
 
         return {
             "version_triple": version_triple,
             "guid": str(guid),
             "install_scope": install_scope,
+            # Template forward compatibility flags
+            # 2022-06-29: #775 added the need to pass for -arch 64 to candle.exe;
+            # Briefcase v0.3.8 didn't use that flag.
+            "_use_arch64": True,
         }
 
     def install_app_support_package(self, app: BaseConfig):
@@ -187,6 +191,8 @@ class WindowsMSIPackageCommand(WindowsMSIMixin, PackageCommand):
                         "WixUtilExtension",
                         "-ext",
                         "WixUIExtension",
+                        "-arch",
+                        "x64",
                         "-dSourceDir=src",
                         f"{app.app_name}.wxs",
                         f"{app.app_name}-manifest.wxs",


Test patch:
diff --git a/tests/platforms/windows/msi/test_create.py b/tests/platforms/windows/msi/test_create.py
index c01e00b1..9bbb09ed 100644
--- a/tests/platforms/windows/msi/test_create.py
+++ b/tests/platforms/windows/msi/test_create.py
@@ -83,7 +83,12 @@ def test_default_install_scope(first_app_config, tmp_path):
 
     context = command.output_format_template_context(first_app_config)
 
-    assert context["install_scope"] == "perUser"
+    assert context == {
+        "guid": "d666a4f1-c7b7-52cc-888a-3a35a7cc97e5",
+        "version_triple": "0.0.1",
+        "install_scope": None,
+        "_use_arch64": True,
+    }
 
 
 def test_per_machine_install_scope(first_app_config, tmp_path):
@@ -93,7 +98,12 @@ def test_per_machine_install_scope(first_app_config, tmp_path):
 
     context = command.output_format_template_context(first_app_config)
 
-    assert context["install_scope"] == "perMachine"
+    assert context == {
+        "guid": "d666a4f1-c7b7-52cc-888a-3a35a7cc97e5",
+        "version_triple": "0.0.1",
+        "install_scope": "perMachine",
+        "_use_arch64": True,
+    }
 
 
 def test_per_user_install_scope(first_app_config, tmp_path):
@@ -103,4 +113,9 @@ def test_per_user_install_scope(first_app_config, tmp_path):
 
     context = command.output_format_template_context(first_app_config)
 
-    assert context["install_scope"] == "perUser"
+    assert context == {
+        "guid": "d666a4f1-c7b7-52cc-888a-3a35a7cc97e5",
+        "version_triple": "0.0.1",
+        "install_scope": "perUser",
+        "_use_arch64": True,
+    }
diff --git a/tests/platforms/windows/msi/test_package.py b/tests/platforms/windows/msi/test_package.py
index ed4725e7..52c136fe 100644
--- a/tests/platforms/windows/msi/test_package.py
+++ b/tests/platforms/windows/msi/test_package.py
@@ -54,6 +54,8 @@ def test_package_msi(package_command, first_app_config, tmp_path):
                     "WixUtilExtension",
                     "-ext",
                     "WixUIExtension",
+                    "-arch",
+                    "x64",
                     "-dSourceDir=src",
                     "first-app.wxs",
                     "first-app-manifest.wxs",