/// <summary>
        /// This function can be called twice.
        ///
        /// First time, it simply check connectivity with a short timeout.
        /// If it does not connect, there are two possibilities.
        ///   1) Firewall was just enabled, let's check for longer time.
        ///   2) Remote powershell is disabled on target machine etc.
        ///
        /// Since we are not clear which is the case, we return null. It will then show
        /// the dialog UI to ask user to choose if he wants to retry testing connectivity.
        ///
        /// If the user choose yes for retry, this method is called the second time.
        /// The second time, we keep testing connectivity with a longer period of time.
        ///
        /// Both times,
        /// if remote powershell can be connected, go to install, start remote debugger step.
        ///
        /// If it is determined it won't connect successfully,
        /// go to a help page with a link to our documentation.
        /// </summary>
        protected override async Task <IAttachDebuggerStep> GetNextStepAsync()
        {
            SetStage(Stage.CheckingConnectivity);
            var  port      = Context.RemotePowerShellPort;
            int  waitTime  = port.WaitForFirewallRuleTimeInSeconds();
            bool connected = waitTime > 0 && _askedToCheckConnectivityLater ?
                             // This is the second time, check connectivity with a longer wait time.
                             await ConnectivityTestUntillTimeoutAsync(waitTime) :
                             // This is the first time, we don't check "waitTime", test connectivity anyhow.
                             await port.ConnectivityTestAsync(CancelToken);

            if (connected)
            {
                return(InstallStartRemoteToolStepViewModel.CreateStep(Context));
            }
            // else: not connected

            // If this is first time call, then check if firewall was just enabled.
            if (!_askedToCheckConnectivityLater && port.WaitForFirewallRuleTimeInSeconds() > 0)
            {
                SetStage(Stage.AskToCheckConnectivityLater);
                _askedToCheckConnectivityLater = true;
                return(null);
            }
            else
            {
                return(HelpStepViewModel.CreateStep(Context));
            }
        }
예제 #2
0
        public override Task <IAttachDebuggerStep> OnStartAsync()
        {
            ProgressMessage       = Resources.AttachDebuggerConnectingProgressMessage;
            IsCancelButtonEnabled = false;

            if (!WindowsCredentialManager.Write(
                    Context.PublicIp,
                    Context.Credential.User,
                    Context.Credential.Password,
                    WindowsCredentialManager.CredentialType.DomainPassword,
                    WindowsCredentialManager.CredentialPersistence.Session))
            {
                Debug.WriteLine($"Failed to save credential for {Context.PublicIp}, last error is {Marshal.GetLastWin32Error()}");
                // It's OKay to continue, the Debugger2 will prompt UI to ask for credential.
            }
            if (!GetAllProcessesList())
            {
                return(Task.FromResult <IAttachDebuggerStep>(HelpStepViewModel.CreateStep(Context)));
            }
            else if (Processes.Count() == 1)
            {
                return(Task.FromResult(Attach()));
            }
            else
            {
                EnableSelection();
                // Returns null so that the user stays on the step to pick a process.
                return(Task.FromResult <IAttachDebuggerStep>(null));
            }
        }
예제 #3
0
        /// <summary>
        /// Creates the step that asks user to open online documentation.
        /// </summary>
        public static HelpStepViewModel CreateStep(AttachDebuggerContext context)
        {
            var content = new HelpStepContent();
            var step    = new HelpStepViewModel(content, context);

            content.DataContext = step;
            return(step);
        }
예제 #4
0
        private IAttachDebuggerStep Attach()
        {
            IsListVisible   = false;
            ProgressMessage = String.Format(
                Resources.AttachDebuggerAttachingProcessMessageFormat,
                SelectedProcess.Name);

            var startTimestamp = DateTime.Now;

            try
            {
                if (SelectedEngine == s_detectEngineTypeItemName)
                {
                    SelectedProcess.Process.Attach();
                }
                else
                {
                    SelectedProcess.Process.Attach2(SelectedEngine);
                }
            }
            catch (COMException ex)
            {
                EventsReporterWrapper.ReportEvent(
                    RemoteDebuggerAttachedEvent.Create(CommandStatus.Failure));

                Debug.WriteLine($"Attach debugger got exception. {ex}");
                UserPromptUtils.ErrorPrompt(
                    message: String.Format(Resources.AttachDebuggerAttachErrorMessageFormat, SelectedProcess.Name),
                    title: Resources.UiDefaultPromptTitle);
                ResetDefaultSelection();
                return(HelpStepViewModel.CreateStep(Context));
            }

            EventsReporterWrapper.ReportEvent(RemoteDebuggerAttachedEvent.Create(
                                                  CommandStatus.Success, DateTime.Now - startTimestamp));

            Context.DialogWindow.Close();
            return(null);
        }
예제 #5
0
        public override async Task <IAttachDebuggerStep> OnStartAsync()
        {
            IsCancelButtonEnabled = true;
            ProgressMessage       = Resources.AttachDebuggerInstallSetupProgressMessage;

            bool installed = false;

            var startTimestamp = DateTime.Now;

            // The following try catch is for adding Analytics in failure case.
            try
            {
                installed = await _installer.Install(CancelToken);
            }
            catch (PowerShellFailedToConnectException)
            {
                UserPromptUtils.ErrorPrompt(
                    message: Resources.AttachDebuggerConnectionFailedMessage,
                    title: Resources.UiDefaultPromptTitle);
            }
            catch (Exception ex) when(!ErrorHandlerUtils.IsCriticalException(ex))
            {
                Debug.WriteLine($"{ex}");
                UserPromptUtils.ErrorPrompt(
                    message: Resources.AttachDebuggerInstallerError,
                    title: Resources.UiDefaultPromptTitle,
                    errorDetails: ex.Message);
            }

            if (installed)
            {
                EventsReporterWrapper.ReportEvent(RemoteDebuggerRemoteToolsInstalledEvent.Create(
                                                      CommandStatus.Success, DateTime.Now - startTimestamp));
            }
            else if (!CancelToken.IsCancellationRequested)
            {
                EventsReporterWrapper.ReportEvent(
                    RemoteDebuggerRemoteToolsInstalledEvent.Create(CommandStatus.Failure));
            }

            if (installed)
            {
                // Reset start time to measure performance of starting remote tools
                startTimestamp = DateTime.Now;

                RemoteToolSession session;

                // The following try catch is for adding analytics where there is exception
                try
                {
                    session = new RemoteToolSession(
                        Context.PublicIp,
                        Context.Credential.User,
                        Context.Credential.Password,
                        GoogleCloudExtensionPackage.Instance.SubscribeClosingEvent,
                        GoogleCloudExtensionPackage.Instance.UnsubscribeClosingEvent);
                }
                catch (Exception ex) when(!ErrorHandlerUtils.IsCriticalException(ex))
                {
                    EventsReporterWrapper.ReportEvent(
                        RemoteDebuggerRemoteToolsStartedEvent.Create(CommandStatus.Failure));
                    throw;
                }

                ProgressMessage = String.Format(
                    Resources.AttachDebuggerTestConnectPortMessageFormat,
                    Context.DebuggerPort.Description,
                    Context.PublicIp,
                    Context.DebuggerPort.PortInfo.Port);

                Stopwatch watch = Stopwatch.StartNew();
                while (!CancelToken.IsCancellationRequested &&
                       watch.Elapsed < s_waitConnectionTimeout &&
                       !session.IsStopped)
                {
                    if (await Context.DebuggerPort.ConnectivityTest(CancelToken))
                    {
                        EventsReporterWrapper.ReportEvent(RemoteDebuggerRemoteToolsStartedEvent.Create(
                                                              CommandStatus.Success, DateTime.Now - startTimestamp));
                        return(ListProcessStepViewModel.CreateStep(Context));
                    }
                    await Task.Delay(500);
                }

                EventsReporterWrapper.ReportEvent(
                    RemoteDebuggerRemoteToolsStartedEvent.Create(CommandStatus.Failure));
            }

            return(HelpStepViewModel.CreateStep(Context));
        }