Beispiel #1
0
 /// <summary>
 /// Used to verify attachment to a runspace
 /// </summary>
 /// <param name="preScenario">The debug scenario before invoking Enter-PSHostProcess</param>
 /// <returns>Empty string if attachment was verified, string describing the result otherwise</returns>
 public string VerifyAttachToRunspace(DebugScenario preScenario, AutoResetEvent attachSemaphore)
 {
     if (preScenario != DebugScenario.RemoteSession)
     {
         // for local attach, we have to wait for the runspace to be pushed
         bool didTimeout = !(attachSemaphore.WaitOne(DebugEngineConstants.AttachRequestEventTimeout));
         if (didTimeout)
         {
             // if semaphore times out, check to see if runspace looks ok, if it does then we will move forward
             if (_debuggingService.GetDebugScenario() != DebugScenario.LocalAttach)
             {
                 ServiceCommon.Log("Unable to attach to local process. Semaphore timed out and runspace is confirmed to not be local attach.");
                 return(Resources.ProcessAttachFailErrorBody);
             }
         }
     }
     else
     {
         // if remote attaching, make sure that we are still in a remote session after entering the host
         DebugScenario scenario = _debuggingService.GetDebugScenario();
         if (scenario != DebugScenario.RemoteSession)
         {
             ServiceCommon.Log("Failed to attach to remote process; scenario after invoke: {0}", scenario);
             return(Resources.ProcessAttachFailErrorBody);
         }
     }
     return(string.Empty);
 }
    public void SetupScenario()
    {
        switch (currentScenario)
        {
        case DebugScenarioType.NEW_USER:      //all items locked but one
        case DebugScenarioType.NEW_USER_RICH: //all items unlocked but one
        {
            DebugScenario scenario = scenarios.Find(a => a.scenarioType == currentScenario);
            GameManager.Instance.Debug_NewUserScenario();
            GameManager.Instance.Debug_AddCurrency(scenario.initialCurrencies);
        }
        break;

        case DebugScenarioType.ALL_UNLOCKED:      //all items unlocked but one
        {
            DebugScenario scenario = scenarios.Find(a => a.scenarioType == currentScenario);
            GameManager.Instance.Debug_UnlockAllItems();
            GameManager.Instance.Debug_AddCurrency(scenario.initialCurrencies);
        }
        break;

        case DebugScenarioType.CUSTOM:
            break;

        case DebugScenarioType.NONE:
            break;

        default:
            break;
        }
    }
Beispiel #3
0
 /// <summary>
 /// Used to verify detachment from a runspace
 /// </summary>
 /// <param name="preScenario">The debug scenario before invoking Exit-PSHostProcess</param>
 /// <returns>True if the detachment was verified, false otherwise</returns>
 public bool VerifyDetachFromRunspace(DebugScenario preScenario, AutoResetEvent attachSemaphore)
 {
     // wait for invoke to finish swapping the runspaces if detaching from a local process
     if (preScenario == DebugScenario.LocalAttach)
     {
         bool didTimeout = !(attachSemaphore.WaitOne(DebugEngineConstants.AttachRequestEventTimeout));
         if (didTimeout)
         {
             // if semaphore times out, check to see if runspace looks ok, if it does then we will move forward
             if (_debuggingService.GetDebugScenario() != DebugScenario.Local)
             {
                 ServiceCommon.Log("Failed to detach from local process. Semaphore timed out and runspace is confirmed to not be local.");
                 return(false);
             }
         }
     }
     else
     {
         // if remote attaching, make sure that we are still in a remote session after exiting the host
         DebugScenario scenario = _debuggingService.GetDebugScenario();
         if (scenario != DebugScenario.RemoteSession)
         {
             ServiceCommon.Log(string.Format("Failed to detach from remote process; scenario after invoke: {0}", scenario));
             return(false);
         }
     }
     return(true);
 }
Beispiel #4
0
        /// <summary>
        /// Execute the current program node.
        /// </summary>
        /// <remarks>
        /// The node will either be a script file or script content; depending on the node
        /// passed to this function.
        /// </remarks>
        /// <param name="node"></param>
        public void Execute(ScriptProgramNode node)
        {
            CurrentExecutingNode = node;

            if (node.IsAttachedProgram)
            {
                string result = string.Empty;
                if (!node.IsRemoteProgram)
                {
                    result = DebuggingService.AttachToRunspace(node.Process.ProcessId);
                }
                else
                {
                    result = DebuggingService.AttachToRemoteRunspace(node.Process.ProcessId, node.Process.HostName);
                }

                if (!string.IsNullOrEmpty(result))
                {
                    // if either of the attaches returns an error, let the user know
                    MessageBox.Show(result, Resources.AttachErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);

                    // see what state we are in post error, if not in a local state, we need to try and get there
                    DebugScenario postCleanupScenario = DebuggingService.GetDebugScenario();

                    // try as hard as we can to detach/cleanup the mess for the length of CleanupRetryTimeout
                    TimeSpan  retryTimeSpan = TimeSpan.FromMilliseconds(DebugEngineConstants.CleanupRetryTimeout);
                    Stopwatch timeElapsed   = Stopwatch.StartNew();
                    while (timeElapsed.Elapsed < retryTimeSpan && postCleanupScenario != DebugScenario.Local)
                    {
                        postCleanupScenario = DebuggingService.CleanupAttach();
                    }

                    // if our efforts to cleanup the mess were unsuccessful, inform the user
                    if (postCleanupScenario != DebugScenario.Local)
                    {
                        MessageBox.Show(Resources.CleanupErrorMessage, Resources.DetachErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }

                    RefreshPrompt();
                    DebuggerFinished();
                }
            }
            else
            {
                string commandLine = node.FileName;

                if (node.IsFile)
                {
                    commandLine = String.Format(DebugEngineConstants.ExecutionCommandFormat, node.FileName, node.Arguments);
                    HostUi.VsOutputString(string.Format("{0}{1}{2}", GetPrompt(), node.FileName, Environment.NewLine));
                }
                Execute(commandLine);
            }
        }
        public void RemoteRunspaceDetachScenarioInvalid()
        {
            _preScenario = DebugScenario.RemoteAttach;
            var debuggingService = new Mock <IPowerShellDebuggingService>();

            debuggingService.Setup(m => m.GetDebugScenario()).Returns(DebugScenario.RemoteAttach);
            _attachUtilities.DebuggingService = debuggingService.Object;

            _boolResult = _attachUtilities.VerifyDetachFromRunspace(_preScenario, _attachSemaphore);
            Assert.IsFalse(_boolResult);
        }
        public void RemoteRunspaceAttachScenarioInvalid()
        {
            _preScenario = DebugScenario.RemoteSession;
            var debuggingService = new Mock <IPowerShellDebuggingService>();

            debuggingService.Setup(m => m.GetDebugScenario()).Returns(DebugScenario.Local);
            _attachUtilities.DebuggingService = debuggingService.Object;

            _stringResult = _attachUtilities.VerifyAttachToRunspace(_preScenario, _attachSemaphore);
            Assert.IsFalse(string.IsNullOrEmpty(_stringResult));
        }
        public void LocalRunspaceDetachSemaFailScenarioValid()
        {
            _attachSemaphore.Reset();
            _preScenario = DebugScenario.LocalAttach;
            var debuggingService = new Mock <IPowerShellDebuggingService>();

            debuggingService.Setup(m => m.GetDebugScenario()).Returns(DebugScenario.Local);
            _attachUtilities.DebuggingService = debuggingService.Object;

            _boolResult = _attachUtilities.VerifyDetachFromRunspace(_preScenario, _attachSemaphore);
            Assert.IsTrue(_boolResult);
        }
        public void LocalRunspaceAttachSemaFailScenarioValid()
        {
            _attachSemaphore.Reset();
            _preScenario = DebugScenario.Local;
            var debuggingService = new Mock <IPowerShellDebuggingService>();

            debuggingService.Setup(m => m.GetDebugScenario()).Returns(DebugScenario.LocalAttach);
            _attachUtilities.DebuggingService = debuggingService.Object;

            _stringResult = _attachUtilities.VerifyAttachToRunspace(_preScenario, _attachSemaphore);
            Assert.IsTrue(string.IsNullOrEmpty(_stringResult));
        }
        /// <summary>
        /// Used by OpenFileInVS to determine correct error message to display if it is unable to open a file
        /// </summary>
        /// <param name="scenario"></param>
        /// <returns></returns>
        public static string ScenarioToFileOpenErrorMsg(DebugScenario scenario)
        {
            switch (scenario)
            {
            case DebugScenario.Local:
                return(Resources.LocalFileOpenError);

            case DebugScenario.RemoteSession:
                return(Resources.RemoteSessionFileOpenError);

            case DebugScenario.LocalAttach:
                return(Resources.LocalAttachFileOpenError);

            case DebugScenario.RemoteAttach:
                return(Resources.RemoteAttachFileOpenError);

            default:
                return(Resources.DefaultFileOpenError);
            }
        }
        public int Detach()
        {
            Log.Debug("ScriptProgramNode: Entering Detach");

            DebugScenario scenario = Debugger.DebuggingService.GetDebugScenario();
            bool          result   = (scenario == DebugScenario.Local);

            if (scenario == DebugScenario.LocalAttach)
            {
                result = Debugger.DebuggingService.DetachFromRunspace();
            }
            else if (scenario == DebugScenario.RemoteAttach)
            {
                result = Debugger.DebuggingService.DetachFromRemoteRunspace();
            }

            if (!result)
            {
                // try as hard as we can to detach/cleanup the mess for the length of CleanupRetryTimeout
                TimeSpan  retryTimeSpan = TimeSpan.FromMilliseconds(DebugEngineConstants.CleanupRetryTimeout);
                Stopwatch timeElapsed   = Stopwatch.StartNew();
                while (timeElapsed.Elapsed < retryTimeSpan && !result)
                {
                    result = (Debugger.DebuggingService.CleanupAttach() == DebugScenario.Local);
                }
            }

            if (result)
            {
                Debugger.DebuggerFinished();
                Debugger.RefreshPrompt();
            }


            return(result ? VSConstants.S_OK : VSConstants.S_FALSE);
        }
Beispiel #11
0
        /// <summary>
        /// PS debugger stopped event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Debugger_DebuggerStop(object sender, DebuggerStopEventArgs e)
        {
            ServiceCommon.Log("Debugger stopped ...");
            DebugScenario currScenario = GetDebugScenario();

            if (_installedPowerShellVersion < RequiredPowerShellVersionForRemoteSessionDebugging)
            {
                RefreshScopedVariable();
                RefreshCallStack();
            }
            else
            {
                RefreshScopedVariable40();
                RefreshCallStack40();
            }

            ServiceCommon.LogCallbackEvent("Callback to client, and wait for debuggee to resume");
            if (e.Breakpoints.Count > 0)
            {
                LineBreakpoint bp = (LineBreakpoint)e.Breakpoints[0];
                if (_callback != null)
                {
                    string file = bp.Script;
                    if (currScenario != DebugScenario.Local && _mapRemoteToLocal.ContainsKey(bp.Script))
                    {
                        file = _mapRemoteToLocal[bp.Script];
                    }

                    // breakpoint is always hit for this case
                    _callback.DebuggerStopped(new DebuggerStoppedEventArgs(file, bp.Line, bp.Column, true, false));
                }
            }
            else
            {
                if (_callback != null)
                {
                    string file;
                    int    lineNum, column;

                    switch (currScenario)
                    {
                    case DebugScenario.LocalAttach:
                        file    = e.InvocationInfo.ScriptName;
                        lineNum = e.InvocationInfo.ScriptLineNumber;
                        column  = e.InvocationInfo.OffsetInLine;

                        // the stop which occurs after attaching is not associated with a breakpoint and should result in the process' script being opened
                        _callback.DebuggerStopped(new DebuggerStoppedEventArgs(file, lineNum, column, false, true));
                        break;

                    case DebugScenario.RemoteAttach:
                        // copy the remote file over to host machine
                        file    = OpenRemoteAttachedFile(e.InvocationInfo.ScriptName);
                        lineNum = e.InvocationInfo.ScriptLineNumber;
                        column  = e.InvocationInfo.OffsetInLine;

                        // the stop which occurs after attaching is not associated with a breakpoint and should result in the remote process' script being opened
                        _callback.DebuggerStopped(new DebuggerStoppedEventArgs(file, lineNum, column, false, true));
                        _needToCopyRemoteScript = false;
                        break;

                    default:
                        _callback.DebuggerStopped(new DebuggerStoppedEventArgs());
                        break;
                    }
                }
            }

            bool resumed = false;

            while (!resumed)
            {
                _pausedEvent.WaitOne();

                try
                {
                    currScenario = GetDebugScenario();
                    if (!string.IsNullOrEmpty(_debuggingCommand))
                    {
                        if (currScenario == DebugScenario.Local)
                        {
                            // local debugging
                            var output = new Collection <PSObject>();

                            using (var pipeline = (_runspace.CreateNestedPipeline()))
                            {
                                pipeline.Commands.AddScript(_debuggingCommand);
                                pipeline.Commands[0].MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output);
                                output = pipeline.Invoke();
                            }

                            ProcessDebuggingCommandResults(output);
                        }
                        else
                        {
                            // remote session and local attach debugging
                            ProcessRemoteDebuggingCommandResults(ExecuteDebuggingCommand());
                        }
                    }
                    else
                    {
                        ServiceCommon.Log(string.Format("Debuggee resume action is {0}", _resumeAction));
                        e.ResumeAction = _resumeAction;
                        resumed        = true; // debugger resumed executing
                    }
                }
                catch (Exception ex)
                {
                    NotifyOutputString(ex.Message);
                }

                // Notify the debugging command execution call that debugging command was complete.
                _debugCommandEvent.Set();
            }
        }
        /// <summary>
        /// Asks HostService to find all attachable processes on the given machine. Will prompt user to retry connecting if
        /// the call to EnumerateRemoteProcesses returns null.
        /// </summary>
        /// <param name="remotePort"></param>
        public void connect(IDebugPort2 remotePort, bool useSSL)
        {
            // Make sure user is starting from a local scenario
            DebugScenario scenario = PowerShellToolsPackage.Debugger.DebuggingService.GetDebugScenario();

            if (scenario != DebugScenario.Local)
            {
                Log.Debug(string.Format("User is trying to remote attach while already in {0}", scenario));
                if (scenario == DebugScenario.RemoteSession)
                {
                    MessageBox.Show(Resources.AttachExistingRemoteError, Resources.AttachErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    MessageBox.Show(Resources.AttachExistingAttachError, Resources.AttachErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                // host needs to be initialized before we can connect/enumerate
                UiContextUtilities.ActivateUiContext(UiContextUtilities.CreateUiContext(Constants.PowerShellReplCreationUiContextGuid));
                if (!PowerShellToolsPackage.PowerShellHostInitialized)
                {
                    // TODO: UI Work required to give user inidcation that it is waiting for debugger to get alive.
                    PowerShellToolsPackage.DebuggerReadyEvent.WaitOne();
                }

                List <KeyValuePair <uint, string> > information;
                string errorMessage = string.Empty;
                while (true)
                {
                    Log.Debug(string.Format("Attempting to find processes on {0}.", _remoteComputer));
                    information = PowerShellToolsPackage.Debugger.DebuggingService.EnumerateRemoteProcesses(_remoteComputer, ref errorMessage, useSSL);

                    if (information != null)
                    {
                        // information now contains list of processes
                        break;
                    }
                    else if (string.IsNullOrEmpty(errorMessage))
                    {
                        // user hit cancel
                        return;
                    }
                    else
                    {
                        // error message was returned
                        DialogResult dlgRes = MessageBox.Show(errorMessage, null, MessageBoxButtons.RetryCancel, MessageBoxIcon.Error);
                        if (dlgRes != DialogResult.Retry)
                        {
                            return;
                        }
                    }
                }

                foreach (KeyValuePair <uint, string> info in information)
                {
                    _runningProcesses.Add(new ScriptDebugProcess(remotePort, info.Key, info.Value, _remoteComputer));
                }
            }
        }