int IDebugRemoteCorDebug.CreateProcessEx(Microsoft.VisualStudio.Debugger.Interop.IDebugPort2 pPort, string lpApplicationName, string lpCommandLine, System.IntPtr lpProcessAttributes, System.IntPtr lpThreadAttributes, int bInheritHandles, uint dwCreationFlags, System.IntPtr lpEnvironment, string lpCurrentDirectory, ref CorDebugInterop._STARTUPINFO lpStartupInfo, ref CorDebugInterop._PROCESS_INFORMATION lpProcessInformation, uint debuggingFlags, out object ppProcess)
        {
            ppProcess = null;

            try
            {
                // CreateProcessEx() is guaranteed to return a valid process object, or throw an exception
                CorDebugProcess process = CorDebugProcess.CreateProcessEx(pPort, lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, ref lpStartupInfo, ref lpProcessInformation, debuggingFlags);

                // StartDebugging() will either get a connected device into a debuggable state and start the dispatch thread, or throw.
                process.StartDebugging(this, true);
                ppProcess = process;

                return(COM_HResults.S_OK);
            }
            catch (ProcessExitException)
            {
                MessageCentre.DebugMessage(Resources.ResourceStrings.InitializeProcessFailedProcessDied);
                return(COM_HResults.S_FALSE);
            }
            catch (Exception ex)
            {
                MessageCentre.DebugMessage(Resources.ResourceStrings.InitializeProcessFailed);
                MessageCentre.InternalErrorMessage(false, ex.Message);
                return(COM_HResults.S_FALSE);
            }
        }
        int IDebugRemoteCorDebug.DebugActiveProcessEx(IDebugPort2 pPort, uint id, int win32Attach, out object ppProcess)
        {
            ppProcess = null;
            try
            {
                MessageCentre.DebugMessage(Resources.ResourceStrings.Attach);
                AD_PROCESS_ID pid = new AD_PROCESS_ID();

                pid.ProcessIdType = (uint)AD_PROCESS_ID_TYPE.AD_PROCESS_ID_SYSTEM;

                pid.dwProcessId = id;

                IDebugProcess2 iDebugProcess;
                pPort.GetProcess(pid, out iDebugProcess);

                CorDebugProcess process = (CorDebugProcess)iDebugProcess;

                // StartDebugging() will either get a connected device into a debuggable state and start the dispatch thread, or throw.
                process.StartDebugging(this, false);
                ppProcess = process;

                return(COM_HResults.S_OK);
            }
            catch (ProcessExitException)
            {
                MessageCentre.DebugMessage(Resources.ResourceStrings.AttachFailedProcessDied);
                return(COM_HResults.S_FALSE);
            }
            catch (Exception ex)
            {
                MessageCentre.DebugMessage(Resources.ResourceStrings.AttachFailed);
                MessageCentre.InternalErrorMessage(false, ex.Message);
                return(COM_HResults.S_FALSE);
            }
        }
        public CorDebugProcess GetDeviceProcess(string deviceName, int eachSecondRetryMaxCount)
        {
            if (string.IsNullOrEmpty(deviceName))
            {
                throw new Exception("DebugPort.GetDeviceProcess() called with no argument");
            }

            MessageCentre.StartProgressMessage(String.Format(Resources.ResourceStrings.StartDeviceSearch, deviceName, eachSecondRetryMaxCount));

            CorDebugProcess process = InternalGetDeviceProcess(deviceName);

            if (process != null)
            {
                return(process);
            }

            if (eachSecondRetryMaxCount < 0)
            {
                eachSecondRetryMaxCount = 0;
            }

            for (int i = 0; i < eachSecondRetryMaxCount && process == null; i++)
            {
                System.Threading.Thread.Sleep(1000);
                process = InternalGetDeviceProcess(deviceName);
            }

            MessageCentre.StopProgressMessage(String.Format((process == null)
                                                                    ? Resources.ResourceStrings.DeviceFound
                                                                    : Resources.ResourceStrings.DeviceNotFound,
                                                            deviceName));
            return(process);
        }
Esempio n. 4
0
        /// <summary>
        /// Handler for PingDeviceCommand
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="arguments"></param>
        /// <remarks>OK to use async void because this is a top-level event-handler
        /// https://channel9.msdn.com/Series/Three-Essential-Tips-for-Async/Tip-1-Async-void-is-for-top-level-event-handlers-only
        /// </remarks>
        private async void PingDeviceCommandHandler(object sender, EventArgs arguments)
        {
            // yield to give the UI thread a chance to respond to user input
            await Task.Yield();

            MessageCentre.StartProgressMessage($"Pinging {ViewModelLocator.DeviceExplorer.SelectedDevice.Description}...");
            try
            {
                // disable the button
                (sender as MenuCommand).Enabled = false;

                // make sure this device is showing as selected in Device Explorer tree view
                await ThreadHelper.JoinableTaskFactory.RunAsync(async() =>
                {
                    ViewModelLocator.DeviceExplorer.ForceNanoDeviceSelection();
                });

                // check if debugger engine exists
                if (NanoDeviceCommService.Device.DebugEngine == null)
                {
                    NanoDeviceCommService.Device.CreateDebugEngine();
                }

                // connect to the device
                if (await NanoDeviceCommService.Device.DebugEngine.ConnectAsync(5000))
                {
                    // ping device
                    var connection = NanoDeviceCommService.Device.Ping();

                    switch (ViewModelLocator.DeviceExplorer.SelectedDevice.DebugEngine.ConnectionSource)
                    {
                    case Tools.Debugger.WireProtocol.ConnectionSource.Unknown:
                        MessageCentre.OutputMessage($"No reply from {ViewModelLocator.DeviceExplorer.SelectedDevice.Description}");
                        break;

                    case Tools.Debugger.WireProtocol.ConnectionSource.nanoBooter:
                    case Tools.Debugger.WireProtocol.ConnectionSource.nanoCLR:
                        MessageCentre.OutputMessage($"{ViewModelLocator.DeviceExplorer.SelectedDevice.Description} is active running {ViewModelLocator.DeviceExplorer.SelectedDevice.DebugEngine.ConnectionSource.ToString()}");
                        break;
                    }
                }
                else
                {
                    MessageCentre.OutputMessage($"{ViewModelLocator.DeviceExplorer.SelectedDevice.Description} is not responding, please reboot the device.");
                }
            }
            catch (Exception ex)
            {
            }
            finally
            {
                // enable the button
                (sender as MenuCommand).Enabled = true;

                MessageCentre.StopProgressMessage();
            }
        }
        protected override byte[] GenerateCode(string inputFileName, string inputFileContent)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            MemoryStream outputStream = new MemoryStream();
            StreamWriter streamWriter = new StreamWriter(outputStream);
            string       inputFileNameWithoutExtension = Path.GetFileNameWithoutExtension(inputFileName);

            // get VS extension assembly to reach ProcessResourceFiles type
            Assembly buildTasks = GetType().Assembly;

            Type typ = buildTasks.GetType("nanoFramework.Tools.ProcessResourceFiles");

            if (typ != null)
            {
                object processResourceFiles = typ.GetConstructor(new Type[] { }).Invoke(null);

                typ.GetProperty("StronglyTypedClassName").SetValue(processResourceFiles, inputFileNameWithoutExtension, null);
                typ.GetProperty("StronglyTypedNamespace").SetValue(processResourceFiles, GetResourcesNamespace(), null);
                typ.GetProperty("GenerateNestedEnums").SetValue(processResourceFiles, m_fNestedEnums, null);
                typ.GetProperty("GenerateInternalClass").SetValue(processResourceFiles, m_fInternal, null);
                typ.GetProperty("IsMscorlib").SetValue(processResourceFiles, m_fMscorlib, null);

                string resourceName = (string)typ.GetProperty("StronglyTypedNamespace").GetValue(processResourceFiles, null);

                if (string.IsNullOrEmpty(resourceName))
                {
                    resourceName = inputFileNameWithoutExtension;
                }
                else
                {
                    resourceName = string.Format("{0}.{1}", resourceName, inputFileNameWithoutExtension);
                }

                typ.GetMethod("CreateStronglyTypedResources").Invoke(processResourceFiles, new object[] { inputFileName, CodeProvider, streamWriter, resourceName });
            }
            else
            {
                // this shouldn't happen
                MessageCentre.InternalErrorMessage("Exception when generating code-behind file. ProcessResourceFiles type missing. Please reinstall the nanoFramework extension.");
            }

            return(base.StreamToBytes(outputStream));
        }
        private void OutputWelcomeMessage()
        {
            System.Threading.Tasks.Task.Run(() =>
            {
                // schedule this to wait for a few seconds before doing it's thing allow VS to load
                System.Threading.Tasks.Task.Delay(5000);

                // loaded
                MessageCentre.OutputMessage($"** nanoFramework extension v{NanoFrameworkExtensionVersion.ToString()} loaded **");

                // intro messages
                MessageCentre.OutputMessage("GitHub repo: https://github.com/nanoframework/Home");
                MessageCentre.OutputMessage("Report issues: https://github.com/nanoframework/Home/issues");
                MessageCentre.OutputMessage("Join our Discord community: https://discord.gg/gCyBu8T");
                MessageCentre.OutputMessage("Join our Hackster.io platform: https://www.hackster.io/nanoframework");
                MessageCentre.OutputMessage("Follow us on Twitter: https://twitter.com/nanoframework");
                MessageCentre.OutputMessage("Follow our YouTube channel: https://www.youtube.com/channel/UC62nKcuCEhvUKHd9k9QEezQ");
                MessageCentre.OutputMessage("Star our GitHub repos: https://github.com/nanoframework/Home");
                MessageCentre.OutputMessage("Add a short review or rate the VS extension: https://marketplace.visualstudio.com/items?itemName=vs-publisher-1470366.nanoFrameworkVS2017Extension");
                MessageCentre.OutputMessage(Environment.NewLine);
            });
        }
        /// <summary>
        /// Initialization of the package; this method is called right after the package is sited, so this is the place
        /// where you can put all the initialization code that rely on services provided by VisualStudio.
        /// </summary>
        protected override async System.Threading.Tasks.Task InitializeAsync(CancellationToken cancellationToken, IProgress <ServiceProgressData> progress)
        {
            // make sure "our" key exists and it's writeable
            s_instance.UserRegistryRoot.CreateSubKey(EXTENSION_SUBKEY, true);

            AddService(typeof(NanoDeviceCommService), CreateNanoDeviceCommServiceAsync);

            // Need to add the View model Locator to the application resource dictionary programmatically
            // because at the extension level we don't have 'XAML' access to it
            // try to find if the view model locator is already in the app resources dictionary
            if (System.Windows.Application.Current.TryFindResource("Locator") == null)
            {
                // instantiate the view model locator...
                ViewModelLocator = new ViewModelLocator();

                // ... and add it there
                System.Windows.Application.Current.Resources.Add("Locator", ViewModelLocator);
            }

            SimpleIoc.Default.GetInstance <DeviceExplorerViewModel>().Package = this;

            await MessageCentre.InitializeAsync(this, "nanoFramework Extension");

            await DeviceExplorerCommand.InitializeAsync(this, ViewModelLocator, await GetServiceAsync(typeof(NanoDeviceCommService)) as INanoDeviceCommService);

            DeployProvider.Initialize(this, ViewModelLocator);

            // Enable debugger UI context
            UIContext.FromUIContextGuid(CorDebug.EngineGuid).IsActive = true;

            await TaskScheduler.Default;

            SimpleIoc.Default.GetInstance <DeviceExplorerViewModel>().NanoDeviceCommService = await GetServiceAsync(typeof(NanoDeviceCommService)) as INanoDeviceCommService;

            OutputWelcomeMessage();

            await base.InitializeAsync(cancellationToken, progress);
        }
        private void SaveButton_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            // setup device network configuration block to save
            var networkConfigurationToSave = (DataContext as DeviceExplorerViewModel).DeviceNetworkConfiguration;

            // IPv4 address options
            if (IPv4Automatic.IsChecked.GetValueOrDefault())
            {
                // IPv4 from DHCP
                networkConfigurationToSave.StartupAddressMode = AddressMode.DHCP;

                // clear remaining options
                networkConfigurationToSave.IPv4Address        = IPAddress.None;
                networkConfigurationToSave.IPv4NetMask        = IPAddress.None;
                networkConfigurationToSave.IPv4GatewayAddress = IPAddress.None;
            }
            else
            {
                // IPv4 has static configuration
                networkConfigurationToSave.StartupAddressMode = AddressMode.Static;

                // clear remaining options
                networkConfigurationToSave.IPv4Address        = IPv4Address.GetAddress();
                networkConfigurationToSave.IPv4NetMask        = IPv4NetMask.GetAddress();
                networkConfigurationToSave.IPv4GatewayAddress = IPv4GatewayAddress.GetAddress();
            }

            // IPv4 DNS options
            if (IPv4DnsAutomatic.IsChecked.GetValueOrDefault())
            {
                // IPv4 DNS is automatic and provided by DHCP server
                networkConfigurationToSave.AutomaticDNS = true;

                // clear DNS addresses
                networkConfigurationToSave.IPv4DNSAddress1 = IPAddress.None;
                networkConfigurationToSave.IPv4DNSAddress2 = IPAddress.None;
            }
            else
            {
                // IPv4 DNS is static
                networkConfigurationToSave.AutomaticDNS = false;

                networkConfigurationToSave.IPv4DNSAddress1 = IPv4Dns1Address.GetAddress();
                networkConfigurationToSave.IPv4DNSAddress2 = IPv4Dns2Address.GetAddress();
            }

            // IPv6 options are not being handled for now
            // FIXME
            networkConfigurationToSave.IPv6Address        = IPAddress.None;
            networkConfigurationToSave.IPv6NetMask        = IPAddress.None;
            networkConfigurationToSave.IPv6GatewayAddress = IPAddress.None;
            networkConfigurationToSave.IPv6DNSAddress1    = IPAddress.None;
            networkConfigurationToSave.IPv6DNSAddress2    = IPAddress.None;

            // check MAC address
            try
            {
                var newMACAddress      = MACAddress.Text;
                var newMACAddressArray = newMACAddress.Split(':');
                var dummyMacAddress    = newMACAddressArray.Select(a => byte.Parse(a, System.Globalization.NumberStyles.HexNumber)).ToArray();
            }
            catch (Exception ex)
            {
                // error parsing MAC address field
                throw new Exception("Invalid MAC address format. Check value.");
            }

            // Wi-Fi config
            (DataContext as DeviceExplorerViewModel).DeviceWireless80211Configuration.Password = WiFiPassword.Password;

            MessageCentre.StartProgressMessage($"Uploading network configuration to {(DataContext as DeviceExplorerViewModel).SelectedDevice.Description}...");

            // check if debugger engine exists
            if ((DataContext as DeviceExplorerViewModel).SelectedDevice.DebugEngine == null)
            {
                (DataContext as DeviceExplorerViewModel).SelectedDevice.CreateDebugEngine();
            }

            // save network configuration to target
            if ((DataContext as DeviceExplorerViewModel).SelectedDevice.DebugEngine.UpdateDeviceConfiguration(networkConfigurationToSave, 0))
            {
                if ((DataContext as DeviceExplorerViewModel).DeviceNetworkConfiguration.InterfaceType == NetworkInterfaceType.Wireless80211)
                {
                    // save Wi-Fi profile to target
                    if ((DataContext as DeviceExplorerViewModel).SelectedDevice.DebugEngine.UpdateDeviceConfiguration((DataContext as DeviceExplorerViewModel).DeviceWireless80211Configuration, 0))
                    {
                        MessageCentre.OutputMessage($"{(DataContext as DeviceExplorerViewModel).SelectedDevice.Description} network configuration updated.");
                        MessageCentre.StopProgressMessage();

                        // close on success
                        Close();
                    }
                }
                else
                {
                    // close on success
                    Close();
                }
            }
            else
            {
                MessageCentre.OutputMessage($"Error updating {(DataContext as DeviceExplorerViewModel).SelectedDevice.Description} network configuration.");
                MessageCentre.StopProgressMessage();
            }
        }
        public async Task DeployAsync(CancellationToken cancellationToken, TextWriter outputPaneWriter)
        {
            // just in case....
            if ((_viewModelLocator?.DeviceExplorer.SelectedDevice == null))
            {
                // can't debug
                // throw exception to signal deployment failure
                throw new Exception("There is no device selected. Please select a device in Device Explorer tool window.");
            }

            // get the device here so we are not always carrying the full path to the device
            NanoDeviceBase device = NanoDeviceCommService.Device;

            // user feedback
            await outputPaneWriter.WriteLineAsync($"Getting things ready to deploy assemblies to nanoFramework device: {device.Description}.");

            List <byte[]> assemblies = new List <byte[]>();

            // device needs to be in 'initialized state' for a successful and correct deployment
            // meaning that is not running nor stopped
            int  retryCount = 0;
            bool deviceIsInInitializeState = false;

            try
            {
                // check if debugger engine exists
                if (NanoDeviceCommService.Device.DebugEngine == null)
                {
                    NanoDeviceCommService.Device.CreateDebugEngine();
                }

                // connect to the device
                if (await device.DebugEngine.ConnectAsync(5000, true))
                {
                    // initial check
                    if (device.DebugEngine.IsDeviceInInitializeState())
                    {
                        // set flag
                        deviceIsInInitializeState = true;

                        // device is still in initialization state, try resume execution
                        device.DebugEngine.ResumeExecution();
                    }

                    // handle the workflow required to try resuming the execution on the device
                    // only required if device is not already there
                    // retry 5 times with a 500ms interval between retries
                    while (retryCount++ < _numberOfRetries && deviceIsInInitializeState)
                    {
                        if (!device.DebugEngine.IsDeviceInInitializeState())
                        {
                            // done here
                            deviceIsInInitializeState = false;
                            break;
                        }

                        // provide feedback to user on the 1st pass
                        if (retryCount == 0)
                        {
                            await outputPaneWriter.WriteLineAsync(ResourceStrings.WaitingDeviceInitialization);
                        }

                        if (device.DebugEngine.ConnectionSource == Tools.Debugger.WireProtocol.ConnectionSource.nanoBooter)
                        {
                            // request nanoBooter to load CLR
                            device.DebugEngine.ExecuteMemory(0);
                        }
                        else if (device.DebugEngine.ConnectionSource == Tools.Debugger.WireProtocol.ConnectionSource.nanoCLR)
                        {
                            // already running nanoCLR try rebooting the CLR
                            device.DebugEngine.RebootDevice(RebootOptions.ClrOnly);
                        }

                        // wait before next pass
                        await Task.Delay(TimeSpan.FromMilliseconds(_timeoutMiliseconds));
                    }
                    ;

                    Thread.Yield();

                    // check if device is still in initialized state
                    if (!deviceIsInInitializeState)
                    {
                        // device has left initialization state
                        await outputPaneWriter.WriteLineAsync(ResourceStrings.DeviceInitialized);

                        //////////////////////////////////////////////////////////
                        // sanity check for devices without native assemblies ?!?!
                        if (device.DeviceInfo.NativeAssemblies.Count == 0)
                        {
                            // there are no assemblies deployed?!
                            throw new DeploymentException($"Couldn't find any native assemblies deployed in {_viewModelLocator.DeviceExplorer.SelectedDevice.Description}! If the situation persists reboot the device.");
                        }

                        // For a known project output assembly path, this shall contain the corresponding
                        // ConfiguredProject:
                        Dictionary <string, ConfiguredProject> configuredProjectsByOutputAssemblyPath =
                            new Dictionary <string, ConfiguredProject>();

                        // For a known ConfiguredProject, this shall contain the corresponding project output assembly
                        // path:
                        Dictionary <ConfiguredProject, string> outputAssemblyPathsByConfiguredProject =
                            new Dictionary <ConfiguredProject, string>();

                        // Fill these two dictionaries for all projects contained in the solution
                        // (whether they belong to the deployment or not):
                        await ReferenceCrawler.CollectProjectsAndOutputAssemblyPathsAsync(
                            ProjectService,
                            configuredProjectsByOutputAssemblyPath,
                            outputAssemblyPathsByConfiguredProject);

                        // This HashSet shall contain a list of full paths to all assemblies to be deployed, including
                        // the compiled output assemblies of our solution's project and also all assemblies such as
                        // NuGet packages referenced by those projects.
                        // The HashSet will take care of only containing any string once even if added multiple times.
                        // However, this is dependent on getting all paths always in the same casing.
                        // Be aware that on file systems which ignore casing, we would end up having assemblies added
                        // more than once here if the GetFullPathAsync() methods used below should not always reliably
                        // return the path to the same assembly in the same casing.
                        HashSet <string> assemblyPathsToDeploy = new HashSet <string>();

                        // Starting with the startup project, collect all assemblies to be deployed.
                        // This will only add assemblies of projects which are actually referenced directly or
                        // indirectly by the startup project. Any project in the solution which is not referenced
                        // directly or indirectly by the startup project will not be included in the list of assemblies
                        // to be deployed.
                        await ReferenceCrawler.CollectAssembliesToDeployAsync(
                            configuredProjectsByOutputAssemblyPath,
                            outputAssemblyPathsByConfiguredProject,
                            assemblyPathsToDeploy,
                            Properties.ConfiguredProject);

                        // build a list with the full path for each DLL, referenced DLL and EXE
                        List <(string path, string version)> assemblyList = new List <(string path, string version)>();

                        foreach (string assemblyPath in assemblyPathsToDeploy)
                        {
                            // load assembly to get the version
                            var assembly = Assembly.Load(File.ReadAllBytes(assemblyPath)).GetName();
                            assemblyList.Add((assemblyPath, $"{assembly.Version.ToString(4)}"));
                        }

                        // if there are referenced project, the assembly list contains repeated assemblies so need to use Linq Distinct()
                        // build a list with the PE files corresponding to each DLL and EXE
                        List <(string path, string version)> peCollection = assemblyList.Distinct().Select(a => (a.path.Replace(".dll", ".pe").Replace(".exe", ".pe"), a.version)).ToList();

                        var checkAssembliesResult = await CheckNativeAssembliesAvailabilityAsync(device.DeviceInfo.NativeAssemblies, peCollection);

                        if (checkAssembliesResult != "")
                        {
                            // can't deploy
                            throw new DeploymentException(checkAssembliesResult);
                        }

                        // Keep track of total assembly size
                        long totalSizeOfAssemblies = 0;

                        // now we will re-deploy all system assemblies
                        foreach ((string path, string version)peItem in peCollection)
                        {
                            // append to the deploy blob the assembly
                            using (FileStream fs = File.Open(peItem.path, FileMode.Open, FileAccess.Read))
                            {
                                long length = (fs.Length + 3) / 4 * 4;
                                await outputPaneWriter.WriteLineAsync($"Adding {Path.GetFileNameWithoutExtension(peItem.path)} v{peItem.version} ({length.ToString()} bytes) to deployment bundle");

                                byte[] buffer = new byte[length];

                                await fs.ReadAsync(buffer, 0, (int)fs.Length);

                                assemblies.Add(buffer);

                                // Increment totalizer
                                totalSizeOfAssemblies += length;
                            }
                        }

                        await outputPaneWriter.WriteLineAsync($"Deploying {peCollection.Count:N0} assemblies to device... Total size in bytes is {totalSizeOfAssemblies.ToString()}.");

                        Thread.Yield();

                        if (!device.DebugEngine.DeploymentExecute(assemblies, false))
                        {
                            // throw exception to signal deployment failure
                            throw new DeploymentException("Deploy failed.");
                        }

                        Thread.Yield();

                        // deployment successful
                        await outputPaneWriter.WriteLineAsync("Deployment successful.");

                        // reset the hash for the connected device so the deployment information can be refreshed
                        _viewModelLocator.DeviceExplorer.LastDeviceConnectedHash = 0;
                    }
                    else
                    {
                        // after retry policy applied seems that we couldn't resume execution on the device...
                        // throw exception to signal deployment failure
                        throw new DeploymentException(ResourceStrings.DeviceInitializationTimeout);
                    }
                }
                else
                {
                    // throw exception to signal deployment failure
                    throw new DeploymentException($"{_viewModelLocator.DeviceExplorer.SelectedDevice.Description} is not responding. Please retry the deployment. If the situation persists reboot the device.");
                }
            }
            catch (DeploymentException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                MessageCentre.InternalErrorMessage($"Unhandled exception with deployment provider: {ex.Message}.");

                throw new Exception("Unexpected error. Please retry the deployment. If the situation persists reboot the device.");
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Handler for RebootCommand
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="arguments"></param>
        /// <remarks>OK to use async void because this is a top-level event-handler
        /// https://channel9.msdn.com/Series/Three-Essential-Tips-for-Async/Tip-1-Async-void-is-for-top-level-event-handlers-only
        /// </remarks>
        private async void RebootCommandHandler(object sender, EventArgs arguments)
        {
            // yield to give the UI thread a chance to respond to user input
            await Task.Yield();

            try
            {
                // disable the button
                (sender as MenuCommand).Enabled = false;

                // make sure this device is showing as selected in Device Explorer tree view
                await ThreadHelper.JoinableTaskFactory.RunAsync(async() =>
                {
                    ViewModelLocator.DeviceExplorer.ForceNanoDeviceSelection();
                });

                // check if debugger engine exists
                if (NanoDeviceCommService.Device.DebugEngine == null)
                {
                    NanoDeviceCommService.Device.CreateDebugEngine();
                }

                // connect to the device
                if (await NanoDeviceCommService.Device.DebugEngine.ConnectAsync(5000))
                {
                    try
                    {
                        NanoDeviceCommService.Device.DebugEngine.RebootDevice(Debugger.RebootOptions.NormalReboot);

                        MessageCentre.OutputMessage($"Sent reboot command to {ViewModelLocator.DeviceExplorer.SelectedDevice.Description}.");

                        // reset the hash for the connected device so the deployment information can be refreshed, if and when requested
                        ViewModelLocator.DeviceExplorer.LastDeviceConnectedHash = 0;

                        // yield to give the UI thread a chance to respond to user input
                        await Task.Yield();
                    }
                    catch
                    {
                        // report issue to user
                        MessageCentre.OutputMessage($"Error sending reboot command to {ViewModelLocator.DeviceExplorer.SelectedDevice.Description}.");

                        return;
                    }
                }
                else
                {
                    // reset property to force that device capabilities are retrieved on next connection
                    ViewModelLocator.DeviceExplorer.LastDeviceConnectedHash = 0;

                    MessageCentre.OutputMessage($"{ViewModelLocator.DeviceExplorer.SelectedDevice.Description} is not responding, please reboot the device.");

                    return;
                }
            }
            catch (Exception ex)
            {
            }
            finally
            {
                // enable the button
                (sender as MenuCommand).Enabled = true;
            }
        }
Esempio n. 11
0
        /// <summary>
        /// Handler for NetworkConfigCommand
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="arguments"></param>
        /// <remarks>OK to use async void because this is a top-level event-handler
        /// https://channel9.msdn.com/Series/Three-Essential-Tips-for-Async/Tip-1-Async-void-is-for-top-level-event-handlers-only
        /// </remarks>
        private async void NetworkConfigCommandHandler(object sender, EventArgs arguments)
        {
            // yield to give the UI thread a chance to respond to user input
            await Task.Yield();

            try
            {
                // disable the button
                (sender as MenuCommand).Enabled = false;

                // make sure this device is showing as selected in Device Explorer tree view
                await ThreadHelper.JoinableTaskFactory.RunAsync(async() =>
                {
                    ViewModelLocator.DeviceExplorer.ForceNanoDeviceSelection();
                });

                // check if debugger engine exists
                if (NanoDeviceCommService.Device.DebugEngine == null)
                {
                    NanoDeviceCommService.Device.CreateDebugEngine();
                }

                // connect to the device
                if (await NanoDeviceCommService.Device.DebugEngine.ConnectAsync(5000))
                {
                    try
                    {
                        // for now, just get the 1st network configuration, if exists
                        var networkConfigurations = NanoDeviceCommService.Device.DebugEngine.GetAllNetworkConfigurations();

                        if (networkConfigurations.Count > 0)
                        {
                            ViewModelLocator.DeviceExplorer.DeviceNetworkConfiguration = networkConfigurations[0];
                        }
                        else
                        {
                            ViewModelLocator.DeviceExplorer.DeviceNetworkConfiguration = new Debugger.DeviceConfiguration.NetworkConfigurationProperties();
                        }

                        // for now, just get the 1st Wi-Fi configuration, if exists
                        var wirellesConfigurations = NanoDeviceCommService.Device.DebugEngine.GetAllWireless80211Configurations();

                        if (wirellesConfigurations.Count > 0)
                        {
                            ViewModelLocator.DeviceExplorer.DeviceWireless80211Configuration = wirellesConfigurations[0];
                        }
                        else
                        {
                            ViewModelLocator.DeviceExplorer.DeviceWireless80211Configuration = new Debugger.DeviceConfiguration.Wireless80211ConfigurationProperties();
                        }

                        // yield to give the UI thread a chance to respond to user input
                        await Task.Yield();

                        // show network configuration dialogue
                        var networkConfigDialog = new NetworkConfigurationDialog();
                        networkConfigDialog.HasMinimizeButton = false;
                        networkConfigDialog.HasMaximizeButton = false;
                        networkConfigDialog.ShowModal();
                    }
                    catch
                    {
                        // report issue to user
                        MessageCentre.OutputMessage($"Error reading {ViewModelLocator.DeviceExplorer.SelectedDevice.Description} configurations.");

                        return;
                    }
                }
                else
                {
                    MessageCentre.OutputMessage($"{ViewModelLocator.DeviceExplorer.SelectedDevice.Description} is not responding, please reboot the device.");

                    return;
                }
            }
            catch (Exception ex)
            {
            }
            finally
            {
                // enable the button
                (sender as MenuCommand).Enabled = true;

                // clear status bar
                MessageCentre.StopProgressMessage();
            }
        }
Esempio n. 12
0
        /// <summary>
        /// Handler for DeviceCapabilitiesCommand
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="arguments"></param>
        /// <remarks>OK to use async void because this is a top-level event-handler
        /// https://channel9.msdn.com/Series/Three-Essential-Tips-for-Async/Tip-1-Async-void-is-for-top-level-event-handlers-only
        /// </remarks>
        private async void DeviceCapabilitiesCommandHandler(object sender, EventArgs arguments)
        {
            // yield to give the UI thread a chance to respond to user input
            await Task.Yield();

            MessageCentre.StartProgressMessage($"Querying {ViewModelLocator.DeviceExplorer.SelectedDevice.Description} capabilities...");

            try
            {
                // disable the button
                (sender as MenuCommand).Enabled = false;

                // make sure this device is showing as selected in Device Explorer tree view
                await ThreadHelper.JoinableTaskFactory.RunAsync(async() =>
                {
                    ViewModelLocator.DeviceExplorer.ForceNanoDeviceSelection();
                });

                // only query device if it's different
                if (ViewModelLocator.DeviceExplorer.SelectedDevice.Description.GetHashCode() != ViewModelLocator.DeviceExplorer.LastDeviceConnectedHash)
                {
                    // keep device description hash code to avoid get info twice
                    ViewModelLocator.DeviceExplorer.LastDeviceConnectedHash = ViewModelLocator.DeviceExplorer.SelectedDevice.Description.GetHashCode();

                    // check if debugger engine exists
                    if (NanoDeviceCommService.Device.DebugEngine == null)
                    {
                        NanoDeviceCommService.Device.CreateDebugEngine();
                    }

                    // connect to the device
                    if (await NanoDeviceCommService.Device.DebugEngine.ConnectAsync(5000))
                    {
                        try
                        {
                            // get device info
                            var deviceInfo    = NanoDeviceCommService.Device.GetDeviceInfo(true);
                            var memoryMap     = NanoDeviceCommService.Device.DebugEngine.GetMemoryMap();
                            var flashMap      = NanoDeviceCommService.Device.DebugEngine.GetFlashSectorMap();
                            var deploymentMap = NanoDeviceCommService.Device.DebugEngine.GetDeploymentMap();

                            // we have to have a valid device info
                            if (deviceInfo.Valid)
                            {
                                // load view model properties for maps
                                ViewModelLocator.DeviceExplorer.DeviceMemoryMap      = new StringBuilder(memoryMap?.ToStringForOutput() ?? "Empty");
                                ViewModelLocator.DeviceExplorer.DeviceFlashSectorMap = new StringBuilder(flashMap?.ToStringForOutput() ?? "Empty");
                                ViewModelLocator.DeviceExplorer.DeviceDeploymentMap  = new StringBuilder(deploymentMap?.ToStringForOutput() ?? "Empty");

                                // load view model property for system
                                ViewModelLocator.DeviceExplorer.DeviceSystemInfo = new StringBuilder(deviceInfo?.ToString() ?? "Empty");
                            }
                            else
                            {
                                // reset property to force that device capabilities are retrieved on next connection
                                ViewModelLocator.DeviceExplorer.LastDeviceConnectedHash = 0;

                                // report issue to user
                                MessageCentre.OutputMessage($"Error retrieving device information from { ViewModelLocator.DeviceExplorer.SelectedDevice.Description}. Please reconnect device.");

                                return;
                            }
                        }
                        catch
                        {
                            // reset property to force that device capabilities are retrieved on next connection
                            ViewModelLocator.DeviceExplorer.LastDeviceConnectedHash = 0;

                            // report issue to user
                            MessageCentre.OutputMessage($"Error retrieving device information from { ViewModelLocator.DeviceExplorer.SelectedDevice.Description}. Please reconnect device.");

                            return;
                        }
                    }
                    else
                    {
                        // reset property to force that device capabilities are retrieved on next connection
                        ViewModelLocator.DeviceExplorer.LastDeviceConnectedHash = 0;

                        MessageCentre.OutputMessage($"{ViewModelLocator.DeviceExplorer.SelectedDevice.Description} is not responding, please reboot the device.");

                        return;
                    }
                }

                MessageCentre.OutputMessage(string.Empty);
                MessageCentre.OutputMessage(string.Empty);
                MessageCentre.OutputMessage("System Information");
                MessageCentre.OutputMessage(ViewModelLocator.DeviceExplorer.DeviceSystemInfo.ToString());

                MessageCentre.OutputMessage(string.Empty);
                MessageCentre.OutputMessage(string.Empty);
                MessageCentre.OutputMessage("--------------------------------");
                MessageCentre.OutputMessage("::        Memory Map          ::");
                MessageCentre.OutputMessage("--------------------------------");
                MessageCentre.OutputMessage(ViewModelLocator.DeviceExplorer.DeviceMemoryMap.ToString());

                MessageCentre.OutputMessage(string.Empty);
                MessageCentre.OutputMessage(string.Empty);
                MessageCentre.OutputMessage("-----------------------------------------------------------");
                MessageCentre.OutputMessage("::                   Flash Sector Map                    ::");
                MessageCentre.OutputMessage("-----------------------------------------------------------");
                MessageCentre.OutputMessage(ViewModelLocator.DeviceExplorer.DeviceFlashSectorMap.ToString());

                MessageCentre.OutputMessage(string.Empty);
                MessageCentre.OutputMessage(string.Empty);
                MessageCentre.OutputMessage("Deployment Map");
                MessageCentre.OutputMessage(ViewModelLocator.DeviceExplorer.DeviceDeploymentMap.ToString());
                MessageCentre.OutputMessage(string.Empty);
            }
            catch (Exception ex)
            {
            }
            finally
            {
                // enable the button
                (sender as MenuCommand).Enabled = true;

                // clear status bar
                MessageCentre.StopProgressMessage();
            }
        }