Skip to content

Conversation

@Nguyen12345tt
Copy link

@Nguyen12345tt Nguyen12345tt commented Jan 16, 2026

Description

This PR migrates the installer projects (Setup and SetupBundle) from the legacy WiX v3.14 to the modern WiX Toolset v6.

Key Changes

1. WiX v6 Migration:

  • Converted .wixproj files to SDK-style projects (WixToolset.Sdk/6.0.2).
  • Replaced old WiX references with NuGet packages (WixToolset.UI.wixext, WixToolset.Bal.wixext, WixToolset.NetFx.wixext).
  • The build is now self-contained and no longer requires a global WiX installation on the build machine.

3. Build Improvements:

  • Implemented auto-detection for signtool.exe via Windows SDK registry keys. Developers no longer need to manually add signtool to their System PATH environment variable.

Verification

  • Built successfully in both Debug and Release configurations (x64).

Copilot AI review requested due to automatic review settings January 16, 2026 02:23
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates the WiX installer projects from the legacy WiX Toolset v3.14 to WiX v6, converting the projects to SDK-style format with NuGet package references. The migration also includes fixes for C++ runtime dependency issues on older Windows 10 builds and improves developer experience with automatic signtool.exe detection.

Changes:

  • Converted .wixproj files to SDK-style projects using WixToolset.Sdk/6.0.2
  • Updated all WiX source files (.wxs, .wxl, .xslt) from v3 to v4 schema namespaces
  • Implemented auto-detection of signtool.exe from Windows SDK registry

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
SetupBundle/SetupBundle.wixproj Migrated to SDK-style project with NuGet packages and auto-detection for signtool
SetupBundle/Bundle.wxs Updated namespace to v4, changed from Product to Package, hardcoded version and manufacturer
SetupBundle/VisualCppRuntime.wxs Migrated to v4 schema with ExePackagePayload structure
SetupBundle/DotNetFramework.wxs Updated namespace and attribute names for v4 compatibility
SetupBundle/Resources/Theme.wxl Converted from element content to Value attributes for v4
Setup/Setup.wixproj Migrated to SDK-style with HarvestDirectory items for automated component generation
Setup/Product.wxs Changed from Product to Package element with v4 namespace
Setup/Directories.wxs Updated to use StandardDirectory for v4 compatibility
Setup/Shortcuts.wxs Updated namespace to v4
Setup/LegacyCleanup.wxs Updated namespace to v4
Setup/Components/*.wxs Updated namespaces to v4
Setup/Components/Application.xslt Updated namespace and improved file reference syntax

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

</BootstrapperApplication>

<Chain>
<PackageGroupRef Id="NetFx48Web" />
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PackageGroupRef references 'NetFx48Web' but the PackageGroup defined in DotNetFramework.wxs has Id='DotNetFramework'. This mismatch will cause a build error. Change this to <PackageGroupRef Id=\"DotNetFramework\" /> to match the actual PackageGroup definition.

Suggested change
<PackageGroupRef Id="NetFx48Web" />
<PackageGroupRef Id="DotNetFramework" />

Copilot uses AI. Check for mistakes.
</BootstrapperApplication>

<Chain>
<PackageGroupRef Id="NetFx48Web" />
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The VisualCppRuntime PackageGroup is defined in VisualCppRuntime.wxs but is not referenced in the Chain. According to the PR description, one of the key goals is to fix startup crashes on older Windows 10 builds caused by missing C++ runtime dependencies. The VisualCppRuntime must be included in the installation chain. Add <PackageGroupRef Id=\"VisualCppRuntime\" /> before the MsiPackage elements.

Suggested change
<PackageGroupRef Id="NetFx48Web" />
<PackageGroupRef Id="NetFx48Web" />
<PackageGroupRef Id="VisualCppRuntime" />

Copilot uses AI. Check for mistakes.
<PackageGroupRef Id="DotNetFramework" />
<PackageGroupRef Id="VisualCppRuntime" />
<MsiPackage Id="SetupX64"
Version="3.8.0">
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The version is hardcoded to '3.8.0' instead of being dynamically bound from the MSI package. In the original code, this used !(bind.packageVersion.SetupX86) to extract the version from the MSI. With the hardcoded version, any changes to the application version will require manual updates here. Consider using a preprocessor variable or binding to maintain version consistency.

Suggested change
Version="3.8.0">
Version="!(bind.packageVersion.SetupX86)">

Copilot uses AI. Check for mistakes.
Comment on lines +3 to +4
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x64</Platform>
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Setup project now defaults to x64 and only includes PropertyGroup configurations for Debug|x64 and Release|x64 (lines 11-17), but the Bundle.wxs still references both x86 and x64 MSI packages (SetupX86 and SetupX64). The x86 platform support has been removed from Setup.wixproj, which will cause the build to fail when SetupBundle tries to include the non-existent x86 MSI. Either restore x86 platform configurations or remove the SetupX86 reference from Bundle.wxs.

Copilot uses AI. Check for mistakes.
</Target>

<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
<Exec Command="IF NOT EXIST &quot;C:\Temp&quot; ( mkdir &quot;C:\Temp&quot; )&#xD;&#xA;curl &quot;https://go.microsoft.com/fwlink/%3fLinkId=2085155&quot; -L -o &quot;C:\Temp\ndp48-web.exe&quot;&#xD;&#xA;curl &quot;https://go.microsoft.com/fwlink/%3fLinkId=2124703&quot; -L -o &quot;C:\Temp\MicrosoftEdgeWebview2Setup.exe&quot;" />
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PreBuild target uses a hardcoded path C:\Temp for downloading dependencies. This path could conflict with other software or be blocked by security policies on some build machines. Consider using $(TEMP), $(TMP), or a project-specific build directory like $(IntermediateOutputPath) to ensure isolation and avoid potential conflicts.

Copilot uses AI. Check for mistakes.
<Bundle Name="Safe Exam Browser"
IconSourceFile="$(var.Setup.ProjectDir)Resources\Application.ico"
Manufacturer="!(bind.packageManufacturer.SetupX86)"
Manufacturer="ETH Zurich"
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Manufacturer has been changed from the dynamic binding !(bind.packageManufacturer.SetupX86) to the hardcoded value 'ETH Zurich'. While this matches the value in Product.wxs, using hardcoded values creates a maintenance burden and risks inconsistency if the manufacturer name is updated in one place but not the other. The original binding approach was more maintainable.

Suggested change
Manufacturer="ETH Zurich"
Manufacturer="!(bind.packageManufacturer.SetupX86)"

Copilot uses AI. Check for mistakes.
<wix:RegistryValue Value="URL:Safe Exam Browser Protocol" Type="string" />
<wix:RegistryValue Name="URL Protocol" Value="" Type="string" />
<wix:RegistryValue Key="DefaultIcon" Value="[#ApplicationIconFile]" Type="string" />
<wix:RegistryValue Key="shell\open\command" Value="&quot;[#MainExecutable]&quot; &quot;%1&quot;" Type="string" />
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The registry value was changed from [ApplicationDirectory]$(var.SafeExamBrowser.Runtime.TargetFileName) to [#MainExecutable]. While [#MainExecutable] is a valid file reference in WiX v4, this change alters the path resolution. The original used a directory property plus filename variable, while the new version uses a file identifier. Verify this produces the correct full path, as the file identifier syntax may expand differently than the directory + filename approach.

Copilot uses AI. Check for mistakes.
@codecov
Copy link

codecov bot commented Jan 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 52.24%. Comparing base (a2b6a7c) to head (98dadcb).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1378      +/-   ##
==========================================
+ Coverage   52.23%   52.24%   +0.01%     
==========================================
  Files         265      265              
  Lines       14498    14498              
  Branches     1589     1589              
==========================================
+ Hits         7573     7575       +2     
+ Misses       6624     6622       -2     
  Partials      301      301              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@dbuechel
Copy link
Member

dbuechel commented Jan 19, 2026

Thanks for your contribution! We have (already for quite some time) a task in our backlog with the aim to update to the latest available WiX Toolset version. Unfortunately, this task has not been prioritized thus far and, at least for the time being, version 3.x seems to still work pretty reliably, so the urgency is comparably low.

Thus, I unfortunately cannot promise that we'll be able to merge the pull request resp. migrate to the latest available version of WiX soon. I'll however advocate again for the changes in the next planning meeting, but the task would even then have to wait for at least the version after next, as the upcoming version 3.11.0 is already completely booked with other priorities.

CORRECTION: The task has meanwhile been moved at the top of the backlog and the changes should, given your generous contribution, be most likely be able to be integrated in version 3.12.0.

@Nguyen12345tt
Copy link
Author

Thank you for the update! It is great to hear that this contribution helps prioritize the migration task.

I completely understand the roadmap for 3.11.0. I am happy to see this slated for version 3.12.0. If you need any adjustments or rebases when the time comes to integrate these changes, just let me know.

@dbuechel
Copy link
Member

dbuechel commented Jan 19, 2026

Thanks a lot, it is much appreciated indeed. We'll definitely let you know if so and will report back once a development build is ready for testing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants