private void BuildAll(bool install = true) { // First build SLN if (!BuildDeployTools.BuildSLN(BuildDeployPrefs.BuildDirectory, false)) { return; } // Next, APPX if (!BuildDeployTools.BuildAppxFromSLN( PlayerSettings.productName, BuildDeployPrefs.MsBuildVersion, BuildDeployPrefs.ForceRebuild, BuildDeployPrefs.BuildConfig, BuildDeployPrefs.BuildPlatform, BuildDeployPrefs.BuildDirectory, BuildDeployPrefs.IncrementBuildVersion, showDialog: !install)) { return; } // Next, Install if (install) { string fullBuildLocation = CalcMostRecentBuild(); string[] ipList = ParseIPList(BuildDeployPrefs.TargetIPs); InstallAppOnDevicesList(fullBuildLocation, ipList); } }
private void OnGUI() { GUILayout.Space(GUISectionOffset); // Setup int buttonWidth_Quarter = Screen.width / 4; int buttonWidth_Half = Screen.width / 2; int buttonWidth_Full = Screen.width - 25; var locatorHasData = XdeGuestLocator.HasData; var locatorIsSearching = XdeGuestLocator.IsSearching; var xdeGuestIpAddress = XdeGuestLocator.GuestIpAddress; // Quick Options GUILayout.BeginVertical(); GUILayout.Label("Quick Options"); EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); // Build & Run button... using (new EditorGUILayout.HorizontalScope()) { GUILayout.FlexibleSpace(); GUI.enabled = ShouldBuildSLNBeEnabled; if (GUILayout.Button((!locatorIsSearching && locatorHasData || HoloLensUsbConnected) ? "Build SLN, Build APPX, then Install" : "Build SLN, Build APPX", GUILayout.Width(buttonWidth_Half - 20))) { // Build SLN EditorApplication.delayCall += () => { BuildAll(!locatorIsSearching && locatorHasData || HoloLensUsbConnected); }; } GUI.enabled = true; if (GUILayout.Button("Open Player Settings", GUILayout.Width(buttonWidth_Quarter))) { EditorApplication.ExecuteMenuItem("Edit/Project Settings/Player"); } if (GUILayout.Button(string.IsNullOrEmpty(wsaCertPath) ? "Select Certificate" : wsaCertPath, GUILayout.Width(buttonWidth_Quarter))) { string path = EditorUtility.OpenFilePanel("Select Certificate", Application.dataPath, "pfx"); wsaCertPath = path.Substring(path.LastIndexOf("/", StringComparison.Ordinal) + 1); if (!string.IsNullOrEmpty(path)) { CertificatePasswordWindow.Show(path); } else { PlayerSettings.WSA.SetCertificate(string.Empty, string.Empty); } } } GUILayout.EndVertical(); // Build section GUILayout.BeginVertical(); GUILayout.Label("SLN"); EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); // Build directory (and save setting, if it's changed) string curBuildDirectory = BuildDeployPrefs.BuildDirectory; string newBuildDirectory = EditorGUILayout.TextField(new GUIContent(GUIHorizontalSpacer + "Build Directory", "It's recommended to use UWP"), curBuildDirectory); if (newBuildDirectory != curBuildDirectory) { BuildDeployPrefs.BuildDirectory = newBuildDirectory; curBuildDirectory = newBuildDirectory; } GUI.enabled = Directory.Exists(BuildDeployPrefs.AbsoluteBuildDirectory); if (GUILayout.Button("Open Build Directory")) { Process.Start(BuildDeployPrefs.AbsoluteBuildDirectory); } GUI.enabled = true; EditorGUILayout.EndHorizontal(); // Build SLN button using (new EditorGUILayout.HorizontalScope()) { GUILayout.FlexibleSpace(); float previousLabelWidth = EditorGUIUtility.labelWidth; // Generate C# Project References EditorGUIUtility.labelWidth = 105; bool generateReferenceProjects = EditorUserBuildSettings.wsaGenerateReferenceProjects; bool shouldGenerateProjects = EditorGUILayout.Toggle("Unity C# Projects", generateReferenceProjects); if (shouldGenerateProjects != generateReferenceProjects) { EditorUserBuildSettings.wsaGenerateReferenceProjects = shouldGenerateProjects; } // Restore previous label width EditorGUIUtility.labelWidth = previousLabelWidth; GUI.enabled = ShouldOpenSLNBeEnabled; if (GUILayout.Button("Open Project Solution", GUILayout.Width(buttonWidth_Quarter))) { // Open SLN string slnFilename = Path.Combine(curBuildDirectory, PlayerSettings.productName + ".sln"); if (File.Exists(slnFilename)) { var slnFile = new FileInfo(slnFilename); Process.Start(slnFile.FullName); } else if (EditorUtility.DisplayDialog("Solution Not Found", "We couldn't find the Project's Solution. Would you like to Build the project now?", "Yes, Build", "No")) { // Build SLN EditorApplication.delayCall += () => { BuildDeployTools.BuildSLN(curBuildDirectory); }; } } GUI.enabled = ShouldBuildSLNBeEnabled; if (GUILayout.Button("Build Unity Project", GUILayout.Width(buttonWidth_Half))) { // Build SLN EditorApplication.delayCall += () => { BuildDeployTools.BuildSLN(curBuildDirectory); }; } GUI.enabled = true; } // Appx sub-section GUILayout.BeginVertical(); GUILayout.Label("APPX"); GUILayout.BeginHorizontal(); // SDK and MS Build Version(and save setting, if it's changed) string curMSBuildVer = BuildDeployPrefs.MsBuildVersion; string currentSDKVersion = EditorUserBuildSettings.wsaUWPSDK; int currentSDKVersionIndex = 0; int defaultMSBuildVersionIndex = -1; for (var i = 0; i < windowsSdkPaths.Length; i++) { if (string.IsNullOrEmpty(currentSDKVersion)) { currentSDKVersionIndex = windowsSdkPaths.Length - 1; } else { if (windowsSdkPaths[i].Equals(currentSDKVersion)) { currentSDKVersionIndex = i; } if (windowsSdkPaths[i].Equals("10.0.14393.0")) { defaultMSBuildVersionIndex = i; } } } currentSDKVersionIndex = EditorGUILayout.Popup(GUIHorizontalSpacer + "SDK Version", currentSDKVersionIndex, windowsSdkPaths); var curScriptingBackend = PlayerSettings.GetScriptingBackend(BuildTargetGroup.WSA); var newScriptingBackend = (ScriptingImplementation)EditorGUILayout.IntPopup( GUIHorizontalSpacer + "Scripting Backend", (int)curScriptingBackend, new[] { "IL2CPP", ".NET" }, new[] { (int)ScriptingImplementation.IL2CPP, (int)ScriptingImplementation.WinRTDotNET }); if (newScriptingBackend != curScriptingBackend) { PlayerSettings.SetScriptingBackend(BuildTargetGroup.WSA, newScriptingBackend); } string newSDKVersion = windowsSdkPaths[currentSDKVersionIndex]; if (!newSDKVersion.Equals(currentSDKVersion)) { EditorUserBuildSettings.wsaUWPSDK = newSDKVersion; } string newMSBuildVer = currentSDKVersionIndex <= defaultMSBuildVersionIndex ? BuildDeployTools.DefaultMSBuildVersion : "15.0"; if (!newMSBuildVer.Equals(curMSBuildVer)) { BuildDeployPrefs.MsBuildVersion = newMSBuildVer; curMSBuildVer = newMSBuildVer; } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); // Build config (and save setting, if it's changed) string curBuildConfigString = BuildDeployPrefs.BuildConfig; BuildConfigEnum buildConfigOption; if (curBuildConfigString.ToLower().Equals("master")) { buildConfigOption = BuildConfigEnum.Master; } else if (curBuildConfigString.ToLower().Equals("release")) { buildConfigOption = BuildConfigEnum.Release; } else { buildConfigOption = BuildConfigEnum.Debug; } buildConfigOption = (BuildConfigEnum)EditorGUILayout.EnumPopup(GUIHorizontalSpacer + "Build Configuration", buildConfigOption); string buildConfigString = buildConfigOption.ToString(); if (buildConfigString != curBuildConfigString) { BuildDeployPrefs.BuildConfig = buildConfigString; curBuildConfigString = buildConfigString; } // Build Platform (and save setting, if it's changed) string curBuildPlatformString = BuildDeployPrefs.BuildPlatform; BuildPlatformEnum buildPlatformOption; if (curBuildPlatformString.ToLower().Equals("x86")) { buildPlatformOption = BuildPlatformEnum.x86; } else if (curBuildPlatformString.ToLower().Equals("x64")) { buildPlatformOption = BuildPlatformEnum.x64; } else { buildPlatformOption = BuildPlatformEnum.AnyCPU; } buildPlatformOption = (BuildPlatformEnum)EditorGUILayout.EnumPopup(GUIHorizontalSpacer + "Build Platform", buildPlatformOption); string newBuildPlatformString; switch (buildPlatformOption) { case BuildPlatformEnum.AnyCPU: newBuildPlatformString = "Any CPU"; break; case BuildPlatformEnum.x86: case BuildPlatformEnum.x64: newBuildPlatformString = buildPlatformOption.ToString(); break; default: throw new ArgumentOutOfRangeException(); } if (newBuildPlatformString != curBuildPlatformString) { BuildDeployPrefs.BuildPlatform = newBuildPlatformString; curBuildPlatformString = newBuildPlatformString; } GUILayout.EndHorizontal(); // Build APPX button using (new EditorGUILayout.HorizontalScope()) { GUILayout.FlexibleSpace(); float previousLabelWidth = EditorGUIUtility.labelWidth; // Force rebuild EditorGUIUtility.labelWidth = 50; bool curForceRebuildAppx = BuildDeployPrefs.ForceRebuild; bool newForceRebuildAppx = EditorGUILayout.Toggle("Rebuild", curForceRebuildAppx); if (newForceRebuildAppx != curForceRebuildAppx) { BuildDeployPrefs.ForceRebuild = newForceRebuildAppx; curForceRebuildAppx = newForceRebuildAppx; } // Increment version EditorGUIUtility.labelWidth = 110; bool curIncrementVersion = BuildDeployPrefs.IncrementBuildVersion; bool newIncrementVersion = EditorGUILayout.Toggle("Increment Version", curIncrementVersion); if (newIncrementVersion != curIncrementVersion) { BuildDeployPrefs.IncrementBuildVersion = newIncrementVersion; curIncrementVersion = newIncrementVersion; } // Restore previous label width EditorGUIUtility.labelWidth = previousLabelWidth; // Build APPX GUI.enabled = ShouldBuildAppxBeEnabled; if (GUILayout.Button("Build APPX", GUILayout.Width(buttonWidth_Half))) { // Open SLN string slnFilename = Path.Combine(curBuildDirectory, PlayerSettings.productName + ".sln"); if (File.Exists(slnFilename)) { // Build APPX EditorApplication.delayCall += () => BuildDeployTools.BuildAppxFromSLN( PlayerSettings.productName, curMSBuildVer, curForceRebuildAppx, curBuildConfigString, curBuildPlatformString, curBuildDirectory, curIncrementVersion); } else if (EditorUtility.DisplayDialog("Solution Not Found", "We couldn't find the solution. Would you like to Build it?", "Yes, Build", "No")) { // Build SLN then APPX EditorApplication.delayCall += () => BuildAll(install: false); } } GUI.enabled = true; } GUILayout.EndVertical(); GUILayout.EndVertical(); GUILayout.Space(GUISectionOffset); // Deploy section GUILayout.BeginVertical(); GUILayout.Label("Deploy"); // Target IPs (and save setting, if it's changed) string curTargetIps = BuildDeployPrefs.TargetIPs; if (!LocalIPsOnly) { string newTargetIPs = EditorGUILayout.TextField( new GUIContent(GUIHorizontalSpacer + "IP Address(es)", "IP(s) of target devices (e.g. 127.0.0.1 | 10.11.12.13)"), curTargetIps); if (newTargetIPs != curTargetIps) { BuildDeployPrefs.TargetIPs = newTargetIPs; curTargetIps = newTargetIPs; } } else { // Queue up a repaint if we're still busy, or we'll get stuck // in a disabled state. if (locatorIsSearching) { Repaint(); } var addressesToPresent = new List <string> { "127.0.0.1" }; if (!locatorIsSearching && locatorHasData) { addressesToPresent.Add(xdeGuestIpAddress.ToString()); } var previouslySavedAddress = addressesToPresent.IndexOf(curTargetIps); if (previouslySavedAddress == -1) { previouslySavedAddress = 0; } EditorGUILayout.BeginHorizontal(); if (locatorIsSearching && !locatorHasData) { GUI.enabled = false; } var selectedAddressIndex = EditorGUILayout.Popup(GUIHorizontalSpacer + "IP Address", previouslySavedAddress, addressesToPresent.ToArray()); if (GUILayout.Button(locatorIsSearching ? "Searching" : "Refresh", GUILayout.Width(buttonWidth_Quarter))) { UpdateXdeStatus(); } GUI.enabled = true; EditorGUILayout.EndHorizontal(); var selectedAddress = addressesToPresent[selectedAddressIndex]; if (curTargetIps != selectedAddress && !locatorIsSearching) { BuildDeployPrefs.TargetIPs = selectedAddress; } } // Username/Password (and save seeings, if changed) string curUsername = BuildDeployPrefs.DeviceUser; string newUsername = EditorGUILayout.TextField(GUIHorizontalSpacer + "Username", curUsername); string curPassword = BuildDeployPrefs.DevicePassword; string newPassword = EditorGUILayout.PasswordField(GUIHorizontalSpacer + "Password", curPassword); bool curFullReinstall = BuildDeployPrefs.FullReinstall; bool newFullReinstall = EditorGUILayout.Toggle( new GUIContent(GUIHorizontalSpacer + "Uninstall First", "Uninstall application before installing"), curFullReinstall); if (newUsername != curUsername || newPassword != curPassword || newFullReinstall != curFullReinstall) { BuildDeployPrefs.DeviceUser = newUsername; BuildDeployPrefs.DevicePassword = newPassword; BuildDeployPrefs.FullReinstall = newFullReinstall; } // Build list (with install buttons) if (builds.Count == 0) { GUILayout.Label(GUIHorizontalSpacer + "*** No builds found in build directory", EditorStyles.boldLabel); } else { GUILayout.BeginVertical(); scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUILayout.Width(buttonWidth_Full), GUILayout.Height(128)); foreach (var fullBuildLocation in builds) { int lastBackslashIndex = fullBuildLocation.LastIndexOf("\\", StringComparison.Ordinal); var directoryDate = Directory.GetLastWriteTime(fullBuildLocation).ToString("yyyy/MM/dd HH:mm:ss"); string packageName = fullBuildLocation.Substring(lastBackslashIndex + 1); EditorGUILayout.BeginHorizontal(); GUILayout.Space(GUISectionOffset + 15); GUI.enabled = (!locatorIsSearching && locatorHasData || HoloLensUsbConnected); if (GUILayout.Button("Install", GUILayout.Width(120.0f))) { string thisBuildLocation = fullBuildLocation; string[] ipList = ParseIPList(curTargetIps); EditorApplication.delayCall += () => { InstallAppOnDevicesList(thisBuildLocation, ipList); }; } GUI.enabled = true; GUILayout.Space(5); GUILayout.Label(packageName + " (" + directoryDate + ")"); EditorGUILayout.EndHorizontal(); } GUILayout.EndScrollView(); GUILayout.EndVertical(); EditorGUILayout.Separator(); } GUILayout.EndVertical(); GUILayout.Space(GUISectionOffset); // Utilities section GUILayout.BeginVertical(); GUILayout.Label("Utilities"); // Open AppX packages location using (new EditorGUILayout.HorizontalScope()) { GUI.enabled = builds.Count > 0; GUILayout.FlexibleSpace(); if (GUILayout.Button("Open APPX Packages Location", GUILayout.Width(buttonWidth_Full))) { Process.Start("explorer.exe", "/f /open," + Path.GetFullPath(curBuildDirectory + "/" + PlayerSettings.productName + "/AppPackages")); } GUI.enabled = true; } // Open web portal using (new EditorGUILayout.HorizontalScope()) { GUI.enabled = ShouldWebPortalBeEnabled && (!locatorIsSearching && locatorHasData || HoloLensUsbConnected); GUILayout.FlexibleSpace(); if (GUILayout.Button("Open Device Portal", GUILayout.Width(buttonWidth_Full))) { OpenWebPortalForIPs(curTargetIps); } GUI.enabled = true; } // Launch app.. using (new EditorGUILayout.HorizontalScope()) { GUI.enabled = ShouldLaunchAppBeEnabled && (!locatorIsSearching && locatorHasData || HoloLensUsbConnected); GUILayout.FlexibleSpace(); if (GUILayout.Button("Launch Application", GUILayout.Width(buttonWidth_Full))) { // If already running, kill it (button is a toggle) if (IsAppRunning_FirstIPCheck(PlayerSettings.productName, curTargetIps)) { KillAppOnIPs(curTargetIps); } else { LaunchAppOnIPs(curTargetIps); } } GUI.enabled = true; } // Log file using (new EditorGUILayout.HorizontalScope()) { string localLogPath = string.Empty; bool localLogExists = false; bool remoteDeviceDetected = !locatorIsSearching && locatorHasData || HoloLensUsbConnected && !string.IsNullOrEmpty(BuildDeployPrefs.TargetIPs); bool isLocalBuild = BuildDeployPrefs.BuildPlatform == BuildPlatformEnum.x64.ToString(); if (!remoteDeviceDetected) { localLogPath = string.Format("%USERPROFILE%\\AppData\\Local\\Packages\\{0}\\TempState\\UnityPlayer.log", PlayerSettings.productName); localLogExists = File.Exists(localLogPath); } GUI.enabled = ShouldLogViewBeEnabled && (remoteDeviceDetected || isLocalBuild && localLogExists); GUILayout.FlexibleSpace(); if (GUILayout.Button("View Log File", GUILayout.Width(buttonWidth_Full))) { if (remoteDeviceDetected) { OpenLogFileForIPs(curTargetIps); } else { Process.Start(localLogPath); } } GUI.enabled = true; } // Uninstall... using (new EditorGUILayout.HorizontalScope()) { GUI.enabled = ShouldLogViewBeEnabled && (!locatorIsSearching && locatorHasData || HoloLensUsbConnected); GUILayout.FlexibleSpace(); if (GUILayout.Button("Uninstall Application", GUILayout.Width(buttonWidth_Full))) { EditorApplication.delayCall += () => { UninstallAppOnDevicesList(ParseIPList(curTargetIps)); }; } GUI.enabled = true; } //GUILayout.EndScrollView(); GUILayout.EndVertical(); }