/// <summary>
        /// Gets the <see cref="Microsoft.MixedReality.Toolkit.WindowsDevicePortal.AvailableWiFiNetworks"/> of the target device.
        /// </summary>
        /// <param name="interfaceInfo">The GUID for the network interface to use to search for wireless networks, without brackets.</param>
        /// <returns><see cref="Microsoft.MixedReality.Toolkit.WindowsDevicePortal.AvailableWiFiNetworks"/></returns>
        public static async Task <AvailableWiFiNetworks> GetAvailableWiFiNetworksAsync(DeviceInfo targetDevice, InterfaceInfo interfaceInfo)
        {
            var isAuth = await EnsureAuthenticationAsync(targetDevice);

            if (!isAuth)
            {
                return(null);
            }

            string query    = string.Format(WiFiNetworkQuery, FinalizeUrl(targetDevice.IP), $"s?interface={interfaceInfo.GUID}");
            var    response = await RestHelpers.Rest.GetAsync(query, targetDevice.Authorization, readResponseData : true, certificateHandler : DevicePortalCertificateHandler, disposeCertificateHandlerOnDispose : false);

            if (!response.Successful)
            {
                if (response.ResponseCode == 403 && await RefreshCsrfTokenAsync(targetDevice))
                {
                    return(await GetAvailableWiFiNetworksAsync(targetDevice, interfaceInfo));
                }

                Debug.LogError(response.ResponseBody);
                return(null);
            }

            return(JsonUtility.FromJson <AvailableWiFiNetworks>(response.ResponseBody));
        }
 /// <summary>
 /// Opens the Device Portal for the target device.
 /// </summary>
 public static void OpenWebPortal(DeviceInfo targetDevice)
 {
     System.Diagnostics.Process.Start(FinalizeUrl(targetDevice.IP));
 }
        /// <summary>
        /// Installs the target application on the target device.
        /// </summary>
        /// <param name="waitForDone">Should the thread wait until installation is complete?</param>
        /// <returns>True, if Installation was a success.</returns>
        public static async Task <bool> InstallAppAsync(string appFullPath, DeviceInfo targetDevice, bool waitForDone = true)
        {
            Debug.Assert(!string.IsNullOrEmpty(appFullPath));
            var isAuth = await EnsureAuthenticationAsync(targetDevice);

            if (!isAuth)
            {
                return(false);
            }

            Debug.Log($"Starting app install on {targetDevice.ToString()}...");

            // Calculate the cert and dependency paths
            string fileName     = Path.GetFileName(appFullPath);
            string certFullPath = Path.ChangeExtension(appFullPath, ".cer");
            string certName     = Path.GetFileName(certFullPath);

            string arch = "ARM";

            if (appFullPath.Contains("x86"))
            {
                arch = "x86";
            }
            else if (appFullPath.Contains("ARM64"))
            {
                arch = "ARM64";
            }

            string depPath = $@"{Path.GetDirectoryName(appFullPath)}\Dependencies\{arch}\";

            var form = new WWWForm();

            try
            {
                // APPX file
                Debug.Assert(appFullPath != null);
                using (var stream = new FileStream(appFullPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    using (var reader = new BinaryReader(stream))
                    {
                        form.AddBinaryData(fileName, reader.ReadBytes((int)reader.BaseStream.Length), fileName);
                    }
                }

                // CERT file
                Debug.Assert(certFullPath != null);
                using (var stream = new FileStream(certFullPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    using (var reader = new BinaryReader(stream))
                    {
                        form.AddBinaryData(certName, reader.ReadBytes((int)reader.BaseStream.Length), certName);
                    }
                }

                // Dependencies
                IOFileInfo[] depFiles = new DirectoryInfo(depPath).GetFiles();
                foreach (IOFileInfo dep in depFiles)
                {
                    using (var stream = new FileStream(dep.FullName, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        using (var reader = new BinaryReader(stream))
                        {
                            string depFilename = Path.GetFileName(dep.FullName);
                            form.AddBinaryData(depFilename, reader.ReadBytes((int)reader.BaseStream.Length), depFilename);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Debug.LogException(e);
                return(false);
            }

            // Query
            string query = $"{string.Format(InstallQuery, FinalizeUrl(targetDevice.IP))}?package={UnityWebRequest.EscapeURL(fileName)}";

            var response = await RestHelpers.Rest.PostAsync(query, form, targetDevice.Authorization, certificateHandler : DevicePortalCertificateHandler, disposeCertificateHandlerOnDispose : false);

            if (!response.Successful)
            {
                if (response.ResponseCode == 403 && await RefreshCsrfTokenAsync(targetDevice))
                {
                    return(await InstallAppAsync(appFullPath, targetDevice, waitForDone));
                }

                Debug.LogError($"Failed to install {fileName} on {targetDevice.ToString()}.");
                return(false);
            }

            var status = AppInstallStatus.Installing;

            // Wait for done (if requested)
            while (waitForDone && status == AppInstallStatus.Installing)
            {
                status = await GetInstallStatusAsync(targetDevice);

                switch (status)
                {
                case AppInstallStatus.InstallSuccess:
                    Debug.Log($"Successfully installed {fileName} on {targetDevice.ToString()}.");
                    return(true);

                case AppInstallStatus.InstallFail:
                    Debug.LogError($"Failed to install {fileName} on {targetDevice.ToString()}.");
                    return(false);
                }
            }

            return(true);
        }
        /// <summary>
        /// Gets the <see cref="Microsoft.MixedReality.Toolkit.WindowsDevicePortal.ApplicationInfo"/> of the target application on the target device.
        /// </summary>
        /// <returns>Returns the <see cref="Microsoft.MixedReality.Toolkit.WindowsDevicePortal.ApplicationInfo"/> of the target application from the target device.</returns>
        private static async Task <ApplicationInfo> GetApplicationInfoAsync(string packageName, DeviceInfo targetDevice)
        {
            Debug.Assert(!string.IsNullOrEmpty(packageName));
            var appList = await GetAllInstalledAppsAsync(targetDevice);

            for (int i = 0; i < appList?.InstalledPackages.Length; ++i)
            {
                if (appList.InstalledPackages[i].PackageFullName.Equals(packageName, StringComparison.OrdinalIgnoreCase))
                {
                    return(appList.InstalledPackages[i]);
                }

                if (appList.InstalledPackages[i].PackageFamilyName.Equals(packageName, StringComparison.OrdinalIgnoreCase))
                {
                    return(appList.InstalledPackages[i]);
                }
            }

            return(null);
        }
 /// <summary>
 /// Determines if the target application is currently running on the target device.
 /// </summary>
 /// <returns>True, if application is currently installed on device.</returns>
 public static async Task <bool> IsAppInstalledAsync(string packageName, DeviceInfo targetDevice)
 {
     Debug.Assert(!string.IsNullOrEmpty(packageName));
     return(await GetApplicationInfoAsync(packageName, targetDevice) != null);
 }
예제 #6
0
        /// <summary>
        /// Makes sure the Authentication Headers and CSRF Tokens are set.
        /// </summary>
        /// <param name="targetDevice"></param>
        /// <returns>True if Authentication is successful, otherwise false.</returns>
        public static async Task <bool> EnsureAuthenticationAsync(DeviceInfo targetDevice)
        {
            string auth = Rest.GetBasicAuthentication(targetDevice.User, targetDevice.Password);

            if (targetDevice.Authorization.ContainsKey("Authorization"))
            {
                targetDevice.Authorization["Authorization"] = auth;
            }
            else
            {
                targetDevice.Authorization.Add("Authorization", auth);
            }

            bool success;

            if (!targetDevice.Authorization.ContainsKey("cookie"))
            {
                var response = await DevicePortalAuthorizationAsync(targetDevice);

                success = response.Successful;

                if (success)
                {
                    targetDevice.CsrfToken = response.ResponseBody;

                    // Strip the beginning of the cookie header
                    targetDevice.CsrfToken = targetDevice.CsrfToken.Replace("CSRF-Token=", string.Empty);
                }
                else
                {
                    Debug.LogError($"Authentication failed! {response.ResponseBody}");
                }

                if (!string.IsNullOrEmpty(targetDevice.CsrfToken))
                {
                    if (!targetDevice.Authorization.ContainsKey("cookie"))
                    {
                        targetDevice.Authorization.Add("cookie", targetDevice.CsrfToken);
                    }
                    else
                    {
                        targetDevice.Authorization["cookie"] = targetDevice.CsrfToken;
                    }

                    if (targetDevice.Authorization.ContainsKey("x-csrf-token"))
                    {
                        targetDevice.Authorization["x-csrf-token"] = targetDevice.CsrfToken;
                    }
                    else
                    {
                        targetDevice.Authorization.Add("x-csrf-token", targetDevice.CsrfToken);
                    }
                }
            }
            else
            {
                success = true;
            }

            return(success);
        }
 /// <summary>
 /// Initialize
 /// </summary>
 public DevicePortalConnections(DeviceInfo deviceInfo)
 {
     Connections.Add(deviceInfo);
 }