Commit 0e5f200a authored by David Kline's avatar David Kline
Browse files

fixes for #226, 227 and 228

parent 4fd8709b
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -245,6 +245,22 @@ namespace Microsoft.Tools.WindowsDevicePortal
                    }
                    catch
                    {
                        switch (this.OsEdition)
                        {
                            case "Enterprise":
                            case "Home":
                            case "Professional":
                                platform = DevicePortalPlatforms.Windows;
                                break;

                            case "Mobile":
                                platform = DevicePortalPlatforms.Mobile;
                                break;

                            default:
                                platform = DevicePortalPlatforms.Unknown;
                                break;
                        }
                    }

                    return platform;
+7 −1
Original line number Diff line number Diff line
@@ -152,7 +152,13 @@ namespace Microsoft.Tools.WindowsDevicePortal
            /// </summary>
            public float Level
            {
                get { return 100.0f * ((float)this.RemainingCapacity / this.MaximumCapacity); }
                get 
                { 
                    // Desktop PCs typically do not have a battery, return 100%
                    if (this.MaximumCapacity == 0) { return 100f; }

                    return 100.0f * ((float)this.RemainingCapacity / this.MaximumCapacity);
                }
            }
        }

+148 −2
Original line number Diff line number Diff line
@@ -11,12 +11,11 @@ using System.Runtime.InteropServices.WindowsRuntime;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Security.Credentials;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.Web.Http;
using Windows.Web.Http.Filters;
using Windows.Web.Http.Headers;
using static Microsoft.Tools.WindowsDevicePortal.DevicePortalException;

namespace Microsoft.Tools.WindowsDevicePortal
@@ -112,5 +111,152 @@ namespace Microsoft.Tools.WindowsDevicePortal
            return status;
        }
#pragma warning restore 1998

        public async Task InstallApplicationAsync(
            string appName,
            StorageFile packageFile, 
            List<StorageFile> dependencyFiles,
            StorageFile certificateFile= null,
            short stateCheckIntervalMs = 500,
            short timeoutInMinutes = 15,
            bool uninstallPreviousVersion = true)
        {
            string installPhaseDescription = string.Empty;

            try
            {
                // If appName was not provided, use the package file name
                if (string.IsNullOrWhiteSpace(appName))
                {
                    appName = packageFile.DisplayName;
                }

                // Uninstall the application's previous version, if one exists.
                if (uninstallPreviousVersion)
                {
                    installPhaseDescription = string.Format("Uninstalling any previous version of {0}", appName);
                    this.SendAppInstallStatus(
                        ApplicationInstallStatus.InProgress,
                        ApplicationInstallPhase.UninstallingPreviousVersion,
                        installPhaseDescription);
                    AppPackages installedApps = await this.GetInstalledAppPackagesAsync();
                    foreach (PackageInfo package in installedApps.Packages)
                    {
                        if (package.Name == appName)
                        {
                            await this.UninstallApplicationAsync(package.FullName);
                            break;
                        }
                    }
                }

                // Create the API endpoint and generate a unique boundary string.
                Uri uri;
                string boundaryString;
                this.CreateAppInstallEndpointAndBoundaryString(
                    packageFile.Name,
                    out uri,
                    out boundaryString);

                using (MemoryStream dataStream = new MemoryStream())
                {
                    byte[] data;

                    // Copy the application package.
                    installPhaseDescription = string.Format("Copying: {0}", packageFile.Name);
                    this.SendAppInstallStatus(
                        ApplicationInstallStatus.InProgress,
                        ApplicationInstallPhase.CopyingFile,
                        installPhaseDescription);
                    data = Encoding.ASCII.GetBytes(string.Format("--{0}\r\n", boundaryString));
                    dataStream.Write(data, 0, data.Length);
                    await CopyFileToRequestStream(
                        packageFile,
                        dataStream);

                    // Copy dependency files, if any.
                    foreach (StorageFile depFile in dependencyFiles)
                    {
                        installPhaseDescription = string.Format("Copying: {0}", depFile.Name);
                        this.SendAppInstallStatus(
                            ApplicationInstallStatus.InProgress,
                            ApplicationInstallPhase.CopyingFile,
                            installPhaseDescription);
                        data = Encoding.ASCII.GetBytes(string.Format("\r\n--{0}\r\n", boundaryString));
                        dataStream.Write(data, 0, data.Length);
                        await CopyFileToRequestStream(
                            depFile, 
                            dataStream);
                    }

                    // Copy the certificate file, if provided.
                    if (certificateFile != null)
                    {
                        installPhaseDescription = string.Format("Copying: {0}", certificateFile.Name);
                        this.SendAppInstallStatus(
                            ApplicationInstallStatus.InProgress,
                            ApplicationInstallPhase.CopyingFile,
                            installPhaseDescription);
                        data = Encoding.ASCII.GetBytes(string.Format("\r\n--{0}\r\n", boundaryString));
                        dataStream.Write(data, 0, data.Length);
                        await CopyFileToRequestStream(
                            certificateFile, 
                            dataStream);
                    }

                    // Close the installation request data.
                    data = Encoding.ASCII.GetBytes(string.Format("\r\n--{0}--\r\n", boundaryString));
                    dataStream.Write(data, 0, data.Length);

                    dataStream.Position = 0;

                    string contentType = string.Format("multipart/form-data; boundary={0}", boundaryString);

                    // Make the HTTP request.
                    await this.PostAsync(uri, dataStream, contentType);
                }

                    // Poll the status until complete.
                    ApplicationInstallStatus status = ApplicationInstallStatus.InProgress;
                do
                {
                    installPhaseDescription = string.Format("Installing {0}", appName);
                    this.SendAppInstallStatus(
                        ApplicationInstallStatus.InProgress,
                        ApplicationInstallPhase.Installing,
                        installPhaseDescription);

                    await Task.Delay(TimeSpan.FromMilliseconds(stateCheckIntervalMs));

                    status = await this.GetInstallStatusAsync().ConfigureAwait(false);
                }
                while (status == ApplicationInstallStatus.InProgress);

                installPhaseDescription = string.Format("{0} installed successfully", appName);
                this.SendAppInstallStatus(
                    ApplicationInstallStatus.Completed,
                    ApplicationInstallPhase.Idle,
                    installPhaseDescription);
            }
            catch (Exception e)
            {
                DevicePortalException dpe = e as DevicePortalException;

                if (dpe != null)
                {
                    this.SendAppInstallStatus(
                        ApplicationInstallStatus.Failed,
                        ApplicationInstallPhase.Idle,
                        string.Format("Failed to install {0}: {1}", appName, dpe.Reason));
                }
                else
                {
                    this.SendAppInstallStatus(
                        ApplicationInstallStatus.Failed,
                        ApplicationInstallPhase.Idle,
                        string.Format("Failed to install {0}: {1}", appName, installPhaseDescription));
                }
            }
        }
    }
}
+52 −0
Original line number Diff line number Diff line
//----------------------------------------------------------------------------------------------
// <copyright file="RequestHelpers.cs" company="Microsoft Corporation">
//     Licensed under the MIT License. See LICENSE.TXT in the project root license information.
// </copyright>
//----------------------------------------------------------------------------------------------

using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.Streams;

namespace Microsoft.Tools.WindowsDevicePortal
{
    /// <content>
    /// Methods for working with Http requests.
    /// </content>
    public partial class DevicePortal
    {
        /// <summary>
        /// Copies a file to the specified stream and prepends the necessary content information
        /// required to be part of a multipart form data request.
        /// </summary>
        /// <param name="file">The file to be copied.</param>
        /// <param name="stream">The stream to which the file will be copied.</param>
        private static async Task CopyFileToRequestStream(
            StorageFile file,
            Stream stream)
        {
            byte[] data;
            string fn = file.Name;
            string contentDisposition = string.Format(
                "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n", 
                fn, 
                fn);
            string contentType = "Content-Type: application/octet-stream\r\n\r\n";

            data = Encoding.ASCII.GetBytes(contentDisposition);
            stream.Write(data, 0, data.Length);

            data = Encoding.ASCII.GetBytes(contentType);
            stream.Write(data, 0, data.Length);

            using (IRandomAccessStreamWithContentType ras = await file.OpenReadAsync())
            {
                Stream fs = ras.AsStreamForRead();
                fs.CopyTo(stream);
            }
        }
    }
}
+3 −3
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("WindowsDevicePortalWrapper.UniversalWindows")]
[assembly: AssemblyCopyright("Copyright ©  2016")]
[assembly: AssemblyCopyright("Copyright ©  2016-2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

@@ -29,6 +29,6 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.9.3.0")]
[assembly: AssemblyFileVersion("0.9.3.0")]
[assembly: AssemblyVersion("0.9.4.0")]
[assembly: AssemblyFileVersion("0.9.4.0")]
[assembly: ComVisible(false)]
 No newline at end of file
Loading