Example #1
0
        /// <summary>
        /// Connects to a HoloLens using the provided credentials.
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public async Task ConnectAsync(
            string address,
            string userName,
            string password)
        {
            this.devicePortalConnection = new HoloLensDevicePortalConnection(
                address,
                userName,
                password);
            DevicePortal portal = new DevicePortal(this.devicePortalConnection);

            portal.ConnectionStatus += DevicePortal_ConnectionStatus;

            // We are physically connected to the device.
            // We can safely accept the device's root certificate.
            Certificate certificate = await portal.GetRootDeviceCertificateAsync(true);

            // Establish the connection to the device.
            // TODO: Add support for optionally setting the SSID and key.
            await portal.ConnectAsync(
                null,
                null,
                updateConnection : true,
                manualCertificate : certificate);
        }
        /// <summary>
        /// Connects to a HoloLens using the provided credentials.
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public async Task ConnectAsync(
            string address,
            string userName,
            string password)
        {
            this.devicePortalConnection = new HoloLensDevicePortalConnection(
                address,
                userName,
                password);
            DevicePortal portal = new DevicePortal(this.devicePortalConnection);

            portal.ConnectionStatus += DevicePortal_ConnectionStatus;

            // If the address is localhost (127.0.0.1), we are physically connected
            // to the HoloLens. This allows us to implicitly trust the device
            // certificate.
            //
            // !! NOTE: UWP applications are not allowed to connect to localhost
            // unless explicitly configured.
            // * Development - Visual Studio performs this configuration automatically.
            // * Side-loading - Please see README.md for more details.
            // * Store submissions - Use only non-loopback connections.
            Certificate certificate = await portal.GetRootDeviceCertificateAsync(true);

            // Establish the connection to the device.
            // TODO: Add support for optionally setting the SSID and key.
            await portal.ConnectAsync(
                null,
                null,
                updateConnection : true,
                manualCertificate : certificate);
        }
        /// <summary>
        /// Click handler for the connectToDevice button.
        /// </summary>
        /// <param name="sender">The caller of this method.</param>
        /// <param name="e">The arguments associated with this event.</param>
        private void ConnectToDevice_Click(object sender, RoutedEventArgs e)
        {
            this.EnableConnectionControls(false);
            this.EnableDeviceControls(false);

            this.ClearOutput();

            portal = new DevicePortal(
                new DefaultDevicePortalConnection(
                    this.address.Text,
                    this.username.Text,
                    this.password.Password));

            // Add additional handling for untrusted certs.
            portal.UnvalidatedCert += DoCertValidation;

            StringBuilder sb          = new StringBuilder();
            Task          connectTask = new Task(
                async() =>
            {
                sb.Append(this.MarshalGetCommandOutput());
                sb.AppendLine("Connecting...");
                this.MarshalUpdateCommandOutput(sb.ToString());
                portal.ConnectionStatus += (portal, connectArgs) =>
                {
                    if (connectArgs.Status == DeviceConnectionStatus.Connected)
                    {
                        sb.Append("Connected to: ");
                        sb.AppendLine(portal.Address);
                        sb.Append("OS version: ");
                        sb.AppendLine(portal.OperatingSystemVersion);
                        sb.Append("Device family: ");
                        sb.AppendLine(portal.DeviceFamily);
                        sb.Append("Platform: ");
                        sb.AppendLine(String.Format("{0} ({1})",
                                                    portal.PlatformName,
                                                    portal.Platform.ToString()));
                    }
                    else if (connectArgs.Status == DeviceConnectionStatus.Failed)
                    {
                        sb.AppendLine("Failed to connect to the device.");
                        sb.AppendLine(connectArgs.Message);
                    }
                };

                await portal.ConnectAsync();

                this.MarshalUpdateCommandOutput(sb.ToString());
            });

            Task continuationTask = connectTask.ContinueWith(
                (t) =>
            {
                this.MarshalEnableDeviceControls(true);
                this.MarshalEnableConnectionControls(true);
            });

            connectTask.Start();
        }
        /// <summary>
        /// TextChanged handler for the address text box.
        /// </summary>
        /// <param name="sender">The caller of this method.</param>
        /// <param name="e">The arguments associated with this event.</param>


        private async void btnTakePicture2_Click(object sender, RoutedEventArgs e)
        {
            portal = new DevicePortal(
                new DefaultDevicePortalConnection(HoloLensUrl, "Tolegen", "*****"));

            StringBuilder sb = new StringBuilder();

            sb.Append(this.messageb.Text);
            sb.AppendLine("Connecting...");
            this.messageb.Text       = sb.ToString();
            portal.ConnectionStatus += (portal, connectArgs) =>
            {
                if (connectArgs.Status == DeviceConnectionStatus.Connected)
                {
                    sb.Append("Connected to: ");
                    sb.AppendLine(portal.Address);
                    sb.Append("OS version: ");
                    sb.AppendLine(portal.OperatingSystemVersion);
                    sb.Append("Device family: ");
                    sb.AppendLine(portal.DeviceFamily);
                    sb.Append("Platform: ");
                    sb.AppendLine(String.Format("{0} ({1})",
                                                portal.PlatformName,
                                                portal.Platform.ToString()));
                }
                else if (connectArgs.Status == DeviceConnectionStatus.Failed)
                {
                    sb.AppendLine("Failed to connect to the device.");
                    sb.AppendLine(connectArgs.Message);
                }
            };
            try
            {
                // If the user wants to allow untrusted connections, make a call to GetRootDeviceCertificate
                // with acceptUntrustedCerts set to true. This will enable untrusted connections for the
                // remainder of this session.

                this.certificate = await portal.GetRootDeviceCertificateAsync(true);

                await portal.ConnectAsync(manualCertificate : this.certificate);
            }
            catch (Exception exception)
            {
                sb.AppendLine(exception.Message);
            }
            this.messageb.Text = sb.ToString();
        }
        static private DevicePortal GetConnection(string url, string userName, string password)
        {
            DevicePortal connection = connections.GetOrAdd(url, (key) =>
            {
                var newConnection              = new DevicePortal(new DefaultDevicePortalConnection(key, userName, password));
                newConnection.UnvalidatedCert += Connection_UnvalidatedCert;
                newConnection.ConnectAsync().Wait();

                if (newConnection.ConnectionHttpStatusCode != HttpStatusCode.OK)
                {
                    throw new DevicePortalException(newConnection.ConnectionHttpStatusCode, "Failed to connect to windows develop portal: " + newConnection.ConnectionFailedDescription);
                }

                return(newConnection);
            });

            return(connection);
        }
Example #6
0
        private static bool TryOpenDevicePortalConnection(Uri targetDevice, ParameterHelper parameters, out DevicePortal portal)
        {
            string userName = parameters.GetParameterValue(ParameterHelper.WdpUser);
            string password = parameters.GetParameterValue(ParameterHelper.WdpPassword);

            bool success = true;

            portal = new DevicePortal(new DefaultDevicePortalConnection(targetDevice.ToString(), userName, password));
            try
            {
                // We need to handle this event otherwise remote connection will be rejected if
                // device isn't trusted by local PC
                portal.UnvalidatedCert += DoCertValidation;

                var connectTask = portal.ConnectAsync(updateConnection: false);
                connectTask.Wait();

                if (portal.ConnectionHttpStatusCode != System.Net.HttpStatusCode.OK)
                {
                    if (portal.ConnectionHttpStatusCode == System.Net.HttpStatusCode.Unauthorized)
                    {
                        throw new System.UnauthorizedAccessException("Connection rejected due to missing/incorrect credentials; specify valid credentials with /user and /pwd switches");
                    }
                    else if (!string.IsNullOrEmpty(portal.ConnectionFailedDescription))
                    {
                        throw new System.OperationCanceledException(string.Format("WDP connection failed (HTTP {0}) : {1}", (int)portal.ConnectionHttpStatusCode, portal.ConnectionFailedDescription));
                    }
                    else
                    {
                        throw new System.OperationCanceledException(string.Format("WDP connection failed (HTTP {0}) : no additional information", (int)portal.ConnectionHttpStatusCode));
                    }
                }
            }
            catch (Exception ex)
            {
                bool verbose = parameters.HasFlag(ParameterHelper.VerboseFlag);
                Console.Out.WriteLine("Failed to open DevicePortal connection to '" + portal.Address + "'\n" + (verbose ? ex.ToString() : ex.Message));

                success = false;
            }

            return(success);
        }
Example #7
0
        public async Task ConnectAsync()
        {
            if (_devicePortal != null)
            {
                _devicePortal.ConnectionStatus -= DevicePortal_ConnectionStatus;
            }

            // 入力された情報をもとに接続
            _devicePortal = new DevicePortal(new DefaultDevicePortalConnection(Address, UserName, Password));
            _devicePortal.ConnectionStatus += DevicePortal_ConnectionStatus;
            try
            {
                // 証明書をデバイスポータルから取得して、それを使って接続を行う
                await _devicePortal.ConnectAsync(manualCertificate : await _devicePortal.GetRootDeviceCertificateAsync(true));
            }
            catch (Exception ex)
            {
                Message = ex.Message;
                Debug.WriteLine(ex);
            }
        }
Example #8
0
        /// <summary>
        /// Connects to a device.
        /// </summary>
        /// <param name="connectOptions">Options that specify how the connection is to be established.</param>
        /// <returns></returns>
        public async Task ConnectAsync(
            ConnectOptions connectOptions)
        {
            string address = connectOptions.Address.ToLower();

            if (!address.StartsWith("http"))
            {
                string scheme = "https";

                if ((address == DefaultConnectionAddress) ||
                    (address == DefaultConnectionAddressAsIp))
                {
                    scheme = "http";
                }

                address = string.Format(
                    "{0}://{1}",
                    scheme,
                    address);
            }

            this.devicePortalConnection = new DefaultDevicePortalConnection(
                address,
                connectOptions.UserName,
                connectOptions.Password);
            DevicePortal portal = new DevicePortal(this.devicePortalConnection);

            portal.ConnectionStatus += DevicePortal_ConnectionStatus;

            // We are physically connected to the device.
            // We can safely accept the device's root certificate.
            Certificate certificate = await portal.GetRootDeviceCertificateAsync(true);

            // Establish the connection to the device.
            await portal.ConnectAsync(
                connectOptions.Ssid,
                connectOptions.NetworkKey,
                updateConnection : connectOptions.UpdateConnection,
                manualCertificate : certificate);
        }
Example #9
0
        /// <summary>
        /// Click handler for the connectToDevice button.
        /// </summary>
        /// <param name="sender">The caller of this method.</param>
        /// <param name="e">The arguments associated with this event.</param>
        private async void ConnectToDevice_Click(object sender, RoutedEventArgs e)
        {
            this.EnableConnectionControls(false);
            this.EnableDeviceControls(false);

            this.ClearOutput();

            bool allowUntrusted = this.allowUntrustedCheckbox.IsChecked.Value;

            portal = new DevicePortal(
                new DefaultDevicePortalConnection(
                    this.address.Text,
                    this.username.Text,
                    this.password.Password));

            StringBuilder sb = new StringBuilder();

            sb.Append(this.commandOutput.Text);
            sb.AppendLine("Connecting...");
            this.commandOutput.Text  = sb.ToString();
            portal.ConnectionStatus += (portal, connectArgs) =>
            {
                if (connectArgs.Status == DeviceConnectionStatus.Connected)
                {
                    sb.Append("Connected to: ");
                    sb.AppendLine(portal.Address);
                    sb.Append("OS version: ");
                    sb.AppendLine(portal.OperatingSystemVersion);
                    sb.Append("Device family: ");
                    sb.AppendLine(portal.DeviceFamily);
                    sb.Append("Platform: ");
                    sb.AppendLine(String.Format("{0} ({1})",
                                                portal.PlatformName,
                                                portal.Platform.ToString()));
                }
                else if (connectArgs.Status == DeviceConnectionStatus.Failed)
                {
                    sb.AppendLine("Failed to connect to the device.");
                    sb.AppendLine(connectArgs.Message);
                }
            };

            try
            {
                // If the user wants to allow untrusted connections, make a call to GetRootDeviceCertificate
                // with acceptUntrustedCerts set to true. This will enable untrusted connections for the
                // remainder of this session.
                if (allowUntrusted)
                {
                    this.certificate = await portal.GetRootDeviceCertificateAsync(true);
                }
                await portal.ConnectAsync(manualCertificate : this.certificate);
            }
            catch (Exception exception)
            {
                sb.AppendLine(exception.Message);
            }

            this.commandOutput.Text = sb.ToString();
            EnableDeviceControls(true);
            EnableConnectionControls(true);
        }
Example #10
0
        /// <summary>
        /// Main entry point
        /// </summary>
        /// <param name="args">command line args</param>
        public static void Main(string[] args)
        {
            ParameterHelper parameters = new ParameterHelper();
            Program         app        = new Program();

            string targetConsole = string.Empty;

            try
            {
                parameters.ParseCommandLine(args);

                OperationType operation = OperationType.None;

                if (parameters.HasParameter(ParameterHelper.Operation))
                {
                    operation = OperationStringToEnum(parameters.GetParameterValue("op"));
                }

                // Allow /ip: to still function, even though we've moved to /x: in the documentation.
                if (parameters.HasParameter(ParameterHelper.IpOrHostnameOld) && !parameters.HasParameter(ParameterHelper.IpOrHostname))
                {
                    targetConsole = parameters.GetParameterValue(ParameterHelper.IpOrHostnameOld);
                }
                else if (parameters.HasParameter(ParameterHelper.IpOrHostname))
                {
                    targetConsole = parameters.GetParameterValue(ParameterHelper.IpOrHostname);
                }

                if (string.IsNullOrEmpty(targetConsole))
                {
                    object regValue;
                    regValue = Microsoft.Win32.Registry.GetValue(DefaultConsoleRegkey, null, null);

                    if (regValue == null)
                    {
                        regValue = Microsoft.Win32.Registry.GetValue(DefaultXtfConsoleRegkey, null, null);
                    }

                    if (regValue is string)
                    {
                        targetConsole = regValue as string;
                    }
                    else
                    {
                        throw new Exception("No default console is currently set. Must provide an ip address or hostname to connect to: /x:<ip or hostname>.");
                    }
                }

                string finalConnectionAddress = string.Format("https://{0}:11443", targetConsole);
                string userName = parameters.GetParameterValue(ParameterHelper.WdpUser);
                string password = parameters.GetParameterValue(ParameterHelper.WdpPassword);

                if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
                {
                    try
                    {
                        // No creds were provided on the command line.
                        CredManager.RetrieveStoredCreds(targetConsole, ref userName, ref password);
                    }
                    catch (TypeLoadException)
                    {
                        // Windows 7 doesn't support credential storage so we'll get a TypeLoadException
                        throw new Exception("Credential storage is not supported on your PC. It requires Windows 8+ to run. Please provide the user and password parameters.");
                    }
                }
                else
                {
                    try
                    {
                        // Creds were provided on the command line.
                        CredManager.UpdateStoredCreds(targetConsole, userName, password);
                    }
                    catch (TypeLoadException)
                    {
                        // Do nothing. We can't store these on Win7
                    }
                }

                X509Certificate2 cert = null;

                IDevicePortalConnection connection = new DefaultDevicePortalConnection(finalConnectionAddress, userName, password);

                DevicePortal portal = new DevicePortal(connection);

                if (parameters.HasParameter(ParameterHelper.Cert))
                {
                    string certFile = parameters.GetParameterValue(ParameterHelper.Cert);

                    try
                    {
                        cert = new X509Certificate2(certFile);
                    }
                    catch (Exception e)
                    {
                        throw new Exception(string.Format("Failed to read manual cert file {0}, {1}", certFile, e.Message), e);
                    }
                }

                // Add additional handling for untrusted certs.
                portal.UnvalidatedCert += app.DoCertValidation;

                // If a thumbprint is provided, use it for this connection. Otherwise check the registry.
                if (parameters.HasParameter("thumbprint"))
                {
                    app.AcceptedThumbprint = parameters.GetParameterValue("thumbprint");
                }
                else
                {
                    object regValue;
                    regValue = Microsoft.Win32.Registry.GetValue(DefaultConsoleRegkey, targetConsole, null);

                    if (regValue is string)
                    {
                        app.AcceptedThumbprint = regValue as string;
                    }
                }

                Task connectTask = portal.ConnectAsync(updateConnection: false, manualCertificate: cert);
                connectTask.Wait();

                if (portal.ConnectionHttpStatusCode != HttpStatusCode.OK)
                {
                    if (portal.ConnectionHttpStatusCode == HttpStatusCode.Unauthorized)
                    {
                        if (connection.Credentials == null)
                        {
                            Console.WriteLine("The WDP connection was rejected due to missing credentials.\n\nPlease provide the /user:<username> and /pwd:<pwd> parameters on your first call to WDP.");
                        }
                        else
                        {
                            Console.WriteLine("The WDP connection was rejected due to bad credentials.\n\nPlease check the /user:<username> and /pwd:<pwd> parameters.");
                        }
                    }
                    else if (!string.IsNullOrEmpty(portal.ConnectionFailedDescription))
                    {
                        Console.WriteLine(string.Format("Failed to connect to WDP (HTTP {0}) : {1}", (int)portal.ConnectionHttpStatusCode, portal.ConnectionFailedDescription));
                    }
                    else
                    {
                        Console.WriteLine("Failed to connect to WDP for unknown reason.");
                    }
                }
                else
                {
                    // If the operation is more than a couple lines, it should
                    // live in its own file. These are arranged alphabetically
                    // for ease of use.
                    switch (operation)
                    {
                    case OperationType.AppOperation:
                        AppOperation.HandleOperation(portal, parameters);
                        break;

                    case OperationType.ConfigOperation:
                        ConfigOperation.HandleOperation(portal, parameters);
                        break;

                    case OperationType.ConnectOperation:
                        // User provided a new ip or hostname to set as the default.
                        if (parameters.HasParameter(ParameterHelper.IpOrHostname) || parameters.HasParameter(ParameterHelper.IpOrHostnameOld))
                        {
                            Microsoft.Win32.Registry.SetValue(DefaultConsoleRegkey, null, targetConsole);
                            Console.WriteLine("Default console set to {0}", targetConsole);
                        }
                        else
                        {
                            Console.WriteLine("Connected to Default console: {0}", targetConsole);
                        }

                        if (parameters.HasParameter("thumbprint"))
                        {
                            string thumbprint = parameters.GetParameterValue("thumbprint");
                            Microsoft.Win32.Registry.SetValue(DefaultConsoleRegkey, targetConsole, thumbprint);
                            Console.WriteLine("Thumbprint {0} saved for console with address {1}.", thumbprint, targetConsole);
                        }

                        break;

                    case OperationType.FiddlerOperation:
                        FiddlerOperation.HandleOperation(portal, parameters);
                        break;

                    case OperationType.FileOperation:
                        FileOperation.HandleOperation(portal, parameters);
                        break;

                    case OperationType.InfoOperation:
                        Console.WriteLine("OS version: " + portal.OperatingSystemVersion);
                        Console.WriteLine("Platform: " + portal.PlatformName + " (" + portal.Platform.ToString() + ")");

                        Task <string> getNameTask = portal.GetDeviceNameAsync();
                        getNameTask.Wait();
                        Console.WriteLine("Device name: " + getNameTask.Result);
                        break;

                    case OperationType.InstallOperation:
                        // Ensure we have an IP since SMB might need it for path generation.
                        parameters.AddParameter(ParameterHelper.IpOrHostname, targetConsole);

                        InstallOperation.HandleOperation(portal, parameters);
                        break;

                    case OperationType.ListProcessesOperation:
                        ListProcessesOperation.HandleOperation(portal, parameters);
                        break;

                    case OperationType.RebootOperation:
                        Task rebootTask = portal.RebootAsync();
                        rebootTask.Wait();
                        Console.WriteLine("Rebooting device.");
                        break;

                    case OperationType.SandboxOperation:
                        SandboxOperation.HandleOperation(portal, parameters);
                        break;

                    case OperationType.ScreenshotOperation:
                        ScreenshotOperation.HandleOperation(portal, parameters);
                        break;

                    case OperationType.SystemPerfOperation:
                        SystemPerfOperation.HandleOperation(portal, parameters);
                        break;

                    case OperationType.XblUserOperation:
                        UserOperation.HandleOperation(portal, parameters);
                        break;

                    default:
                        Console.WriteLine("Successfully connected to console but no operation was specified. \n" +
                                          "Use the '/op:<operation type>' parameter to run a specified operation.");
                        Console.WriteLine();
                        Console.WriteLine(AvailableOperationsText);
                        break;
                    }
                }
            }
            catch (AggregateException e)
            {
                if (e.InnerException is DevicePortalException)
                {
                    DevicePortalException innerException = e.InnerException as DevicePortalException;

                    Console.WriteLine(string.Format("Exception encountered: {0}, hr = 0x{1:X} : {2}", innerException.StatusCode, innerException.HResult, innerException.Reason));
                }
                else
                {
                    Console.WriteLine(string.Format("Unexpected exception encountered: {0}", e.Message));
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine();
                Console.WriteLine(GeneralUsageMessage);
            }

            // If a debugger is attached, don't close but instead loop here until
            // closed.
            while (Debugger.IsAttached)
            {
                Thread.Sleep(0);
            }
        }
        /// <summary>
        /// Main entry point
        /// </summary>
        /// <param name="args">command line args</param>
        public static void Main(string[] args)
        {
            ParameterHelper parameters = new ParameterHelper();
            Program         app        = new Program();

            try
            {
                parameters.ParseCommandLine(args);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine();
                Console.WriteLine(GeneralUsageMessage);
                return;
            }

            if (parameters.HasFlag(ParameterHelper.HelpFlag))
            {
                Console.WriteLine(GeneralUsageMessage);
                return;
            }

            if (!parameters.HasParameter(ParameterHelper.FullAddress) || !parameters.HasParameter(ParameterHelper.WdpUser) || !parameters.HasParameter(ParameterHelper.WdpPassword))
            {
                Console.WriteLine("Missing one or more required parameter(s). Must provide address, user, and pwd");
                Console.WriteLine();
                Console.WriteLine(GeneralUsageMessage);
                return;
            }

            IDevicePortalConnection connection = new DefaultDevicePortalConnection(parameters.GetParameterValue(ParameterHelper.FullAddress), parameters.GetParameterValue(ParameterHelper.WdpUser), parameters.GetParameterValue(ParameterHelper.WdpPassword));
            DevicePortal            portal     = new DevicePortal(connection);

            Task connectTask = portal.ConnectAsync(updateConnection: false);

            connectTask.Wait();

            if (portal.ConnectionHttpStatusCode != HttpStatusCode.OK)
            {
                if (!string.IsNullOrEmpty(portal.ConnectionFailedDescription))
                {
                    Console.WriteLine(string.Format("Failed to connect to WDP (HTTP {0}) : {1}", (int)portal.ConnectionHttpStatusCode, portal.ConnectionFailedDescription));
                }
                else
                {
                    Console.WriteLine("Failed to connect to WDP for unknown reason.");
                }

                return;
            }

            string directory = "MockData";

            if (parameters.HasParameter("directory"))
            {
                directory = parameters.GetParameterValue("directory");
            }

            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            if (parameters.HasParameter("endpoint"))
            {
                HttpMethods httpMethod = HttpMethods.Get;

                if (parameters.HasParameter("method"))
                {
                    // This is case sensitive. Since it's only used while generating mocks which is a development time action,
                    // that seems okay. If we want to revisit I'd prefer keeping the casing of the enum and using a switch or
                    // if/else block to manually convert.
                    httpMethod = (HttpMethods)Enum.Parse(typeof(HttpMethods), parameters.GetParameterValue("method"));
                }

                string endpoint = parameters.GetParameterValue("endpoint");

                string requestBodyFile = parameters.GetParameterValue("requestbody");

                if (!string.IsNullOrEmpty(requestBodyFile))
                {
                    if (parameters.HasFlag("requestbodymultipartfile"))
                    {
                        string boundaryString = Guid.NewGuid().ToString();

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

                            FileInfo fi = new FileInfo(requestBodyFile);
                            data = Encoding.ASCII.GetBytes(string.Format("\r\n--{0}\r\n", boundaryString));
                            dataStream.Write(data, 0, data.Length);
                            CopyFileToRequestStream(fi, dataStream);

                            // Close the multipart 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);

                            Task saveResponseTask = portal.SaveEndpointResponseToFileAsync(endpoint, directory, httpMethod, dataStream, contentType);
                            saveResponseTask.Wait();
                        }
                    }
                    else
                    {
                        Stream fileStream = new FileStream(requestBodyFile, FileMode.Open);

                        Task saveResponseTask = portal.SaveEndpointResponseToFileAsync(endpoint, directory, httpMethod, fileStream, "application/json");
                        saveResponseTask.Wait();
                    }
                }
                else
                {
                    Task saveResponseTask = portal.SaveEndpointResponseToFileAsync(endpoint, directory, httpMethod);
                    saveResponseTask.Wait();
                }
            }
            else
            {
                foreach (Endpoint endpoint in Endpoints)
                {
                    HttpMethods httpMethod    = endpoint.Method;
                    string      finalEndpoint = endpoint.Value;

                    try
                    {
                        Task saveResponseTask = portal.SaveEndpointResponseToFileAsync(finalEndpoint, directory, httpMethod);
                        saveResponseTask.Wait();
                    }
                    catch (Exception e)
                    {
                        // Print an error message if possible but continue on.
                        // Not all APIs are available on all device types.
                        if (e.InnerException is DevicePortalException)
                        {
                            DevicePortalException exception = e.InnerException as DevicePortalException;

                            Console.WriteLine(string.Format("Failed to generate .dat for {0} with status {1} ({2}).", endpoint, exception.HResult, exception.Reason));
                        }
                    }
                }
            }

            Console.WriteLine("Data generated in directory {0}.", directory);
            Console.WriteLine();
            Console.WriteLine("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
            Console.WriteLine("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
            Console.WriteLine("Please make sure to remove any personally identifiable information from the\n" +
                              "response(s) (such as alias/emails, ip addresses, and machine names) before\n" +
                              "adding them as mock responses!");
            Console.WriteLine("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
            Console.WriteLine("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");

            // If a debugger is attached, don't close but instead loop here until
            // closed.
            while (Debugger.IsAttached)
            {
                Thread.Sleep(0);
            }
        }