Universal Windows Platform. Build and Run. How does it works behind the scenes?

Hi,

I am trying to replicate the Unity behavior of “build and run” for Universal Windows Platform, to use in a pipeline.

When you press the “Build” button, unity creates a visual studio solution that then you can compile by your own. I have been able to replicate this by

buildPlayerOptions.target = BuildTarget.WSAPlayer;
buildPlayerOptions.targetGroup = BuildTargetGroup.WSA;
BuildPipeline.BuildPlayer(buildPlayerOptions)

However, when you press “Build and Run”, Unity does two things that I have not been able to fully replicate.

1 - Package the solution
This button creates the .sln but, in addition, it uses this solution to generate the package. I assume it is using the visual studio installation under the hood but I’d like to see how it is used and how it uses the parameters

2 - Run the result
When you “build and run” the project targeting to a intel-64 architecture, Unity is able to actually execute the result in windows desktop. But If I double click over the generated application, I get an error. So, how is unity launching the application?

I have been reviewing the UnityCsReference in case I’d find something but I think that code is internal because I couldn’t find anything

Result:

Execution by “Build and Run”:

Execution by double click on REMOVE_Pipeline_Playground.exe
9759813--1397748--upload_2024-4-9_16-47-49.png

You were almost correct that we use Visual Studio to build the generated .sln file: we use msbuild instead. Here’s the command line:

"C:\Program Files\Microsoft Visual Studio\2022\Professional\Msbuild\Current\Bin\MSBuild.exe" "<buildpath>\Project.sln" /nologo /maxcpucount /p:Configuration=Release /p:Platform=x64 /p:SolutionDir="<buildpath>" /t:Build /clp:Verbosity=minimal

Then we use Visual Studio to deploy the app:

"C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\IDE\devenv.com" "<buildpath>\Project.sln" /deploy "Release|x64"

Once the app is registered, we run it via IApplicationActivationManager::ActivateApplication. We ship a helper application in Unity installation that wraps this API (<UNITY_INSTALL_DIR>\Editor\Data\PlaybackEngines\MetroSupport\Tools\UWPPlayerLauncher.exe) and it takes the AppxManifest.xml path which is in the deployed app directory as a parameter:

"<UNITY_INSTALL_DIR>\Editor\Data\PlaybackEngines\MetroSupport\Tools\UWPPlayerLauncher.exe" "<buildpath>\build\bin\x64\Release\AppX\AppxManifest.xml"

If you copy UWPPlayerLauncher.exe into the same folder as the built app, you can just run it without any parameters as then it will pick up AppxManifest.xml from next to it. This is what we do when you select the ExecutableOnly build type in the build window.

Now, you could also just specify BuildOptions.AutoRunPlayer when calling BuildPipeline.BuildPlayer and it’d act as if you pressed Build & Run button instead of the Build button :).

3 Likes

Amazing answer, everything worked as you said, thanks!

By the way, what does this line do? Is it really necessary?

"C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\IDE\devenv.com" "<buildpath>\Project.sln" /deploy "Release|x64"

It “deploys” the app, which is a fancy way of saying it installs/register it with the system. Windows can only run installed UWP apps.

It is not necessary. UWPPlayerLauncher.exe will install it if it’s not installed. But devenv.com tends to give better error messages if something goes wrong.

1 Like