/// <summary> /// Build the Uwp Player. /// </summary> /// <param name="buildInfo"></param> /// <param name="cancellationToken"></param> public static async Task <bool> BuildPlayer(UwpBuildInfo buildInfo, CancellationToken cancellationToken = default) { if (buildInfo.IsCommandLine) { ParseBuildCommandLine(ref buildInfo); } var buildReport = UnityPlayerBuildTools.BuildUnityPlayer(buildInfo); var success = buildReport != null && buildReport.summary.result == BuildResult.Succeeded; if (success && buildInfo.BuildAppx) { success &= await UwpAppxBuildTools.BuildAppxAsync(buildInfo, cancellationToken); } return(success); }
/// <summary> /// Do a build configured for UWP Applications to the specified path, returns the error from <see cref="BuildPlayer(UwpBuildInfo, CancellationToken)"/> /// </summary> /// <param name="buildDirectory"></param> /// <param name="showDialog">Should the user be prompted to build the appx as well?</param> /// <param name="cancellationToken"></param> /// <returns>True, if build was successful.</returns> public static async Task <bool> BuildPlayer(string buildDirectory, bool showDialog = true, CancellationToken cancellationToken = default) { if (UnityPlayerBuildTools.CheckBuildScenes() == false) { return(false); } var buildInfo = new UwpBuildInfo { OutputDirectory = buildDirectory, Scenes = EditorBuildSettings.scenes.Where(scene => scene.enabled).Select(scene => scene.path), BuildAppx = !showDialog, // Configure a post build action that will compile the generated solution PostBuildAction = PostBuildAction }; async void PostBuildAction(IBuildInfo innerBuildInfo, BuildReport buildReport) { if (buildReport.summary.result != BuildResult.Succeeded) { EditorUtility.DisplayDialog($"{PlayerSettings.productName} WindowsStoreApp Build {buildReport.summary.result}!", "See console for details", "OK"); } else { if (showDialog && !EditorUtility.DisplayDialog(PlayerSettings.productName, "Build Complete", "OK", "Build AppX")) { var _buildInfo = innerBuildInfo as UwpBuildInfo; Debug.Assert(_buildInfo != null); EditorAssemblyReloadManager.LockReloadAssemblies = true; await UwpAppxBuildTools.BuildAppxAsync(_buildInfo, cancellationToken); EditorAssemblyReloadManager.LockReloadAssemblies = false; } } } return(await BuildPlayer(buildInfo, cancellationToken)); }
private static void ParseBuildCommandLine(ref UwpBuildInfo buildInfo) { IBuildInfo iBuildInfo = buildInfo; UnityPlayerBuildTools.ParseBuildCommandLine(ref iBuildInfo); string[] arguments = Environment.GetCommandLineArgs(); for (int i = 0; i < arguments.Length; ++i) { switch (arguments[i]) { case "-buildAppx": buildInfo.BuildAppx = true; break; case "-rebuildAppx": buildInfo.RebuildAppx = true; break; } } }
/// <summary> /// Build the UWP appx bundle for this project. Requires that <see cref="UwpPlayerBuildTools.BuildPlayer(string,bool,CancellationToken)"/> has already be run or a user has /// previously built the Unity Player with the WSA Player as the Build Target. /// </summary> /// <param name="buildInfo"></param> /// <param name="cancellationToken"></param> /// <returns>True, if the appx build was successful.</returns> public static async Task <bool> BuildAppxAsync(UwpBuildInfo buildInfo, CancellationToken cancellationToken = default) { if (!EditorAssemblyReloadManager.LockReloadAssemblies) { Debug.LogError("Lock Reload assemblies before attempting to build appx!"); return(false); } if (IsBuilding) { Debug.LogWarning("Build already in progress!"); return(false); } if (Application.isBatchMode) { // We don't need stack traces on all our logs. Makes things a lot easier to read. Application.SetStackTraceLogType(LogType.Log, StackTraceLogType.None); } Debug.Log("Starting Unity Appx Build..."); IsBuilding = true; string slnFilename = Path.Combine(buildInfo.OutputDirectory, $"{PlayerSettings.productName}.sln"); if (!File.Exists(slnFilename)) { Debug.LogError("Unable to find Solution to build from!"); return(IsBuilding = false); } // Get and validate the msBuild path... var msBuildPath = await FindMsBuildPathAsync(); if (!File.Exists(msBuildPath)) { Debug.LogError($"MSBuild.exe is missing or invalid!\n{msBuildPath}"); return(IsBuilding = false); } // Ensure that the generated .appx version increments by modifying Package.appxmanifest try { if (!UpdateAppxManifest(buildInfo)) { throw new Exception(); } } catch (Exception e) { Debug.LogError($"Failed to update appxmanifest!\n{e.Message}"); return(IsBuilding = false); } string storagePath = Path.GetFullPath(Path.Combine(Path.Combine(Application.dataPath, ".."), buildInfo.OutputDirectory)); string solutionProjectPath = Path.GetFullPath(Path.Combine(storagePath, $@"{PlayerSettings.productName}.sln")); // Now do the actual appx build var processResult = await new Process().StartProcessAsync( msBuildPath, $"\"{solutionProjectPath}\" /t:{(buildInfo.RebuildAppx ? "Rebuild" : "Build")} /p:Configuration={buildInfo.Configuration} /p:Platform={buildInfo.BuildPlatform} /verbosity:m", !Application.isBatchMode, cancellationToken); switch (processResult.ExitCode) { case 0: Debug.Log("Appx Build Successful!"); if (Application.isBatchMode) { Debug.Log(string.Join("\n", processResult.Output)); } break; case -1073741510: Debug.LogWarning("The build was terminated either by user's keyboard input CTRL+C or CTRL+Break or closing command prompt window."); break; default: { if (processResult.ExitCode != 0) { Debug.LogError($"{PlayerSettings.productName} appx build Failed! (ErrorCode: {processResult.ExitCode})"); if (Application.isBatchMode) { var buildOutput = "Appx Build Output:\n"; foreach (var message in processResult.Output) { buildOutput += $"{message}\n"; } buildOutput += "Appx Build Errors:"; foreach (var error in processResult.Errors) { buildOutput += $"{error}\n"; } Debug.LogError(buildOutput); } } break; } } AssetDatabase.SaveAssets(); IsBuilding = false; return(processResult.ExitCode == 0); }