public static void Show(string path)
        {
            CertificatePasswordWindow[] array = (CertificatePasswordWindow[])UnityEngine.Resources.FindObjectsOfTypeAll(typeof(CertificatePasswordWindow));
            CertificatePasswordWindow   certificatePasswordWindow = (array.Length <= 0) ? CreateInstance <CertificatePasswordWindow>() : array[0];

            path = path.Replace("\\", "/");
            certificatePasswordWindow.path                   = path.Substring(path.LastIndexOf("Assets/", StringComparison.Ordinal));
            certificatePasswordWindow.password               = string.Empty;
            certificatePasswordWindow.message                = GUIContent.none;
            certificatePasswordWindow.messageStyle           = new GUIStyle(GUI.skin.label);
            certificatePasswordWindow.messageStyle.fontStyle = FontStyle.Italic;
            certificatePasswordWindow.focus                  = "password";
            if (array.Length > 0)
            {
                certificatePasswordWindow.Focus();
            }
            else
            {
                certificatePasswordWindow.titleContent = new GUIContent("Enter Windows Store Certificate Password");
                certificatePasswordWindow.position     = new Rect(100f, 100f, 350f, 90f);
                certificatePasswordWindow.minSize      = new Vector2(certificatePasswordWindow.position.width, certificatePasswordWindow.position.height);
                certificatePasswordWindow.maxSize      = certificatePasswordWindow.minSize;
                certificatePasswordWindow.ShowUtility();
            }
        }
        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();
        }