/// <summary>
        /// Event handler that's called when the connection window is closing.  Clean up all of our threads, exit the PowerShell instance, and dispose of
        /// <see cref="_currentPowerShell"/>.
        /// </summary>
        /// <param name="sender">Object from which this event originated.</param>
        /// <param name="e">Arguments associated with this event.</param>
        protected void ParentForm_Closing(object sender, CancelEventArgs e)
        {
            try
            {
                if (_inputThread != null)
                {
                    _inputThread.Abort();
                }
            }

            catch
            {
            }

            try
            {
                ExecuteQuiet("exit");
            }

            finally
            {
                if (_currentPowerShell != null)
                {
                    _currentPowerShell.Dispose();
                    _currentPowerShell = null;
                }

                _powerShellHost.Exit();
            }
        }
Esempio n. 2
0
 private void HandleJobStateChanged(object sender, JobStateEventArgs e)
 {
     base.SetJobState(e.JobStateInfo.State);
     if (this.IsFinishedState(e.JobStateInfo.State))
     {
         base.PSEndTime = new DateTime?(DateTime.Now);
         System.Management.Automation.PowerShell powerShell = null;
         Runspace runspace = null;
         lock (base.SyncRoot)
         {
             if (this._job != null && this.IsFinishedState(this._job.JobStateInfo.State))
             {
                 this._powerShell = null;
                 this._runspace   = null;
             }
         }
         if (powerShell != null)
         {
             powerShell.Dispose();
         }
         if (runspace != null)
         {
             runspace.Dispose();
         }
         if (this._asyncJobStop)
         {
             this._asyncJobStop = false;
             this.OnStopJobCompleted(new AsyncCompletedEventArgs(null, false, null));
         }
         this.RemoveSetShouldExitFromHost();
     }
 }
Esempio n. 3
0
 /// <summary>
 /// Override EndProcessing.
 /// </summary>
 protected override void EndProcessing()
 {
     if (_powerShell != null)
     {
         _powerShell.Dispose();
     }
 }
        /// <summary>
        /// A helper class that builds and executes a pipeline that writes to the default output path, depending on the value of <paramref name="quiet"/>. Any
        /// exceptions that are thrown are just passed to the caller.
        /// </summary>
        /// <param name="command">The script to run.</param>
        /// <param name="input">Any input arguments to pass to the script. If null then nothing is passed in.</param>
        /// <param name="quiet">Whether or not the results of the call should be written to the console.</param>
        /// <returns>The results of the call to _currentPowerShell.<see cref="PowerShell.Invoke()"/>.</returns>
        protected Collection <PSObject> ExecuteHelper(string command, object input, bool quiet = false)
        {
            // Ignore empty command lines.
            if (String.IsNullOrEmpty(command))
            {
                return(null);
            }

            lock (_executionLock)
            {
                // Create the pipeline object and make it available to the Ctrl-C handle through the _currentPowerShell instance variable.
                lock (_instanceLock)
                {
                    _currentPowerShell = Shell.Create();
                }

                // Create a pipeline for this execution, and then place the result in the _currentPowerShell variable so it is available to be stopped.
                try
                {
                    _currentPowerShell.Runspace = Runspace;
                    _currentPowerShell.AddScript(command);

                    if (!quiet)
                    {
                        // Add the default outputter to the end of the pipe and then call the MergeMyResults method to merge the output and error streams from
                        // the pipeline. This will result in the output being written using the PSHost and PSHostUserInterface classes instead of returning
                        // objects to the host application.
                        _currentPowerShell.AddCommand("out-default");
                        _currentPowerShell.Commands.Commands[0].MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output);
                    }

                    // If there is any input pass it in, otherwise just invoke the the pipeline.
                    if (input != null)
                    {
                        return(_currentPowerShell.Invoke(
                                   new object[]
                        {
                            input
                        }));
                    }

                    else
                    {
                        return(_currentPowerShell.Invoke());
                    }
                }

                finally
                {
                    // Dispose the PowerShell object and set _currentPowerShell to null. It is locked because _currentPowerShell may be accessed by the Ctrl-C
                    // handler.
                    lock (_instanceLock)
                    {
                        _currentPowerShell.Dispose();
                        _currentPowerShell = null;
                    }
                }
            }
        }
Esempio n. 5
0
            /* NOTE: You can see what the ExecutionPolicy is by doing "Get-ExecutionPolicy" (without double quotes).
             * Set the ExecutionPolicy with "Set-ExecutionPolicy -ExecutionPolicy <Restricted/AllSigned/RemoteSigned/Unrestricted>".
             * Add "-Scope CurrentUser" along with Set-ExecutionPolicy to set the ExecutionPolicy for ONLY the CURRENT USER.
             */
            public string runPowerShell(string options, Dictionary <string, string> optionDict)
            {
                // Get script directory and clear session variable
                string scriptDirectory = HttpContext.Current.Session["scriptDirectory"].ToString();

                HttpContext.Current.Session["scriptDirectory"] = "";

                // Clean the Result TextBox
                string output = "Running script... \r\n";

                // Powershell engine
                Runspace runspace = getRunspace();

                using (runspace)
                {
                    runspace.Open();
                    using (System.Management.Automation.PowerShell shell = System.Management.Automation.PowerShell.Create())
                    {
                        shell.Runspace = runspace;

                        // Get script path
                        string scriptPath = getScriptPath(scriptDirectory);
                        output += "Script path: " + scriptPath + "\r\n";
                        output += "Input: " + options + "\r\n";

                        if (File.Exists(scriptPath))
                        {
                            // Add script
                            shell.AddCommand(scriptPath);

                            if (!string.IsNullOrEmpty(options))
                            {
                                // Add parameters and arguments
                                output += "Parsed parameters and arguments: " + string.Join("; ", optionDict.Select(dict => dict.Key + "=" + dict.Value).ToArray()) + "\r\n";
                                foreach (string key in optionDict.Keys)
                                {
                                    if (key.StartsWith("-"))
                                    {
                                        shell.AddParameter(key, optionDict[key]);
                                    }
                                    else
                                    {
                                        shell.AddArgument(key);
                                    }
                                }
                            }
                            shell.AddCommand("Out-String");
                            output += invokeScript(shell);
                        }
                        else
                        {
                            output += "File not found. Please check the file path. Otherwise, please go back to the home page and then try again.";
                        }
                        shell.Dispose();
                    }
                    runspace.Close();
                }
                return(output);
            }
Esempio n. 6
0
 private void ReleaseIndependentShell()
 {
     lock (executionLock)
     {
         independentShell?.Dispose();
         independentShell = null;
     }
 }
Esempio n. 7
0
        public void CleanupPowerShell()
        {
            _ps.Dispose();

            if (File.Exists(_tempFilePath))
            {
                File.Delete(_tempFilePath);
            }
        }
        public void Dispose()
        {
            _ps.Dispose();

            if (File.Exists(_tempFilePath))
            {
                File.Delete(_tempFilePath);
            }
        }
        /// <summary>
        /// To display an exception using the display formatter, run a second pipeline passing in the error record. The runtime will bind this to the $input
        /// variable, which is why $input is being piped to the Out-String cmdlet. The WriteErrorLine method is called to make sure the error gets displayed in
        /// the correct error color.
        /// </summary>
        /// <param name="e">The exception to display.</param>
        private void ReportException(Exception e)
        {
            if (e != null)
            {
                IContainsErrorRecord errorRecord = e as IContainsErrorRecord;
                object error = errorRecord != null
                                                       ? errorRecord.ErrorRecord
                                                       : new ErrorRecord(e, "Host.ReportException", ErrorCategory.NotSpecified, null);

                lock (_instanceLock)
                {
                    _currentPowerShell = Shell.Create();
                }

                _currentPowerShell.Runspace = Runspace;

                try
                {
                    _currentPowerShell.AddScript("$input").AddCommand("out-string");

                    // Do not merge errors, this function will swallow errors.
                    Collection <PSObject>     result;
                    PSDataCollection <object> inputCollection = new PSDataCollection <object>
                    {
                        error
                    };

                    inputCollection.Complete();

                    lock (_executionLock)
                    {
                        result = _currentPowerShell.Invoke(inputCollection);
                    }

                    if (result.Count > 0)
                    {
                        string output = result[0].BaseObject as string;

                        // Remove \r\n, which is added by the Out-String cmdlet.
                        if (!string.IsNullOrEmpty(output))
                        {
                            _powerShellHost.UI.WriteErrorLine(output.Substring(0, output.Length - 2));
                        }
                    }
                }

                finally
                {
                    // Dispose of the pipeline and set it to null, locking it because _currentPowerShell may be accessed by the Ctrl-C handler.
                    lock (_instanceLock)
                    {
                        _currentPowerShell.Dispose();
                        _currentPowerShell = null;
                    }
                }
            }
        }
Esempio n. 10
0
        private void ReleaseShell()
        {
            lock (executionLock)
            {
                cancellationTask?.Dispose();
                cancellationTask = null;

                shell?.Dispose();
                shell = null;
            }
        }
Esempio n. 11
0
 public string[] GetTabCompletion(string commandLine)
 {
     string[] strArrays;
     if (commandLine != null)
     {
         lock (this.clientRequestLock)
         {
             if (this.State == PowwaSession.SessionState.Available)
             {
                 this.State = PowwaSession.SessionState.ExecutingCommand;
                 System.Management.Automation.PowerShell powerShell = null;
                 try
                 {
                     try
                     {
                         powerShell          = System.Management.Automation.PowerShell.Create();
                         powerShell.Runspace = this.Runspace;
                         CommandCompletion commandCompletion = CommandCompletion.CompleteInput(commandLine, commandLine.Length, null, powerShell);
                         string            str        = commandLine.Substring(0, commandCompletion.ReplacementIndex);
                         string[]          strArrays1 = new string[commandCompletion.CompletionMatches.Count];
                         for (int i = 0; i < commandCompletion.CompletionMatches.Count; i++)
                         {
                             strArrays1[i] = string.Concat(str, commandCompletion.CompletionMatches[i].CompletionText);
                         }
                         strArrays = strArrays1;
                     }
                     catch
                     {
                         strArrays = new string[0];
                     }
                 }
                 finally
                 {
                     if (powerShell != null)
                     {
                         powerShell.Dispose();
                     }
                     this.State = PowwaSession.SessionState.Available;
                 }
             }
             else
             {
                 PowwaEvents.PowwaEVENT_DEBUG_LOG1("GetTabCompletion(): Invalid Session State", "SessionState", this.State.ToString());
                 throw new InvalidOperationException("The session is not available");
             }
         }
         return(strArrays);
     }
     else
     {
         throw new ArgumentNullException("commandLine");
     }
 }
        private bool disposedValue = false; // To detect redundant calls

        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    _pwsh.Dispose();
                }

                _pwsh         = null;
                disposedValue = true;
            }
        }
Esempio n. 13
0
        private System.Management.Automation.PowerShell CreatePowerShellObject(PSHost host, string modulePath)
        {
            System.Management.Automation.PowerShell ps = null;
            try
            {
                //loading SHiPS module
                _sessionstate.ImportPSModule(new[] { SHiPSModule });

                //loading dsl module
                if (!string.IsNullOrWhiteSpace(modulePath))
                {
                    _sessionstate.ImportPSModule(new[] { modulePath });
                }
                _runspace = RunspaceFactory.CreateRunspace(host, _sessionstate);

                if (_runspace == null)
                {
                    return(null);
                }
                else
                {
                    _runspace.Open();
                    var error = _runspace.SessionStateProxy.PSVariable.GetValue("Error") as ArrayList;
                    if (error != null && error.Count > 0)
                    {
                        _provider.ThrowTerminatingError(error[0] as ErrorRecord);
                        return(null);
                    }
                    ps = System.Management.Automation.PowerShell.Create();

                    //Cannot use ps.Runspace = Runspace.DefaultRunspace, it will give you an error
                    //Pipelines cannot be run concurrently
                    ps.Runspace = _runspace;
                    return(ps);
                }
            }
            catch (Exception)
            {
                // didn't create or import correctly.
                if (ps != null)
                {
                    ps.Dispose();
                }
                if (_runspace != null)
                {
                    _runspace.Close();
                }

                throw;
            }
        }
Esempio n. 14
0
        /// <summary>
        /// Dispose
        /// </summary>
        /// <param name="disposing"></param>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (_ps.InvocationStateInfo.State == PSInvocationState.Running)
                {
                    _ps.Stop();
                }
                _ps.Dispose();

                _input.Complete();
                _output.Complete();
            }

            base.Dispose(disposing);
        }
Esempio n. 15
0
        /// <summary>
        /// Disposes the pipeline.
        /// </summary>
        /// <param name="disposing">True, when called on Dispose().</param>
        protected override void Dispose(bool disposing)
        {
            try
            {
                if (_disposed)
                {
                    return;
                }

                lock (_syncRoot)
                {
                    if (_disposed)
                    {
                        return;
                    }

                    _disposed = true;
                }

                if (disposing)
                {
                    // wait for the pipeline to stop..this will block
                    // if the pipeline is already stopping.
                    Stop();
                    // _pipelineFinishedEvent.Close();

                    if (_powershell != null)
                    {
                        _powershell.Dispose();
                        _powershell = null;
                    }

                    _inputCollection.Dispose();
                    _inputStream.Dispose();
                    _outputCollection.Dispose();
                    _outputStream.Dispose();
                    _errorCollection.Dispose();
                    _errorStream.Dispose();
                    MethodExecutorStream.Dispose();
                    PipelineFinishedEvent.Dispose();
                }
            }
            finally
            {
                base.Dispose(disposing);
            }
        }
Esempio n. 16
0
        private void HandleJobStateChanged(object sender, JobStateEventArgs e)
        {
            SetJobState(e.JobStateInfo.State);

            if (IsFinishedState(e.JobStateInfo.State))
            {
                PSEndTime = DateTime.Now;

                // Dispose the PowerShell and Runspace objects.
                System.Management.Automation.PowerShell disposePowerShell = null;
                Runspace disposeRunspace = null;
                lock (SyncRoot)
                {
                    if (_job != null &&
                        IsFinishedState(_job.JobStateInfo.State))
                    {
                        disposePowerShell = _powerShell;
                        _powerShell       = null;
                        disposeRunspace   = _runspace;
                        _runspace         = null;
                    }
                }

                if (disposePowerShell != null)
                {
                    disposePowerShell.Dispose();
                }

                if (disposeRunspace != null)
                {
                    disposeRunspace.Dispose();
                }

                // Raise async job stopped event, if needed.
                if (_asyncJobStop)
                {
                    _asyncJobStop = false;
                    OnStopJobCompleted(new AsyncCompletedEventArgs(null, false, null));
                }

                // Remove AllowSetShouldExit from host.
                RemoveSetShouldExitFromHost();
            }
        }
Esempio n. 17
0
        private void ReleaseUnmanagedResources()
        {
            try
            {
                PowerShell?.Dispose();
            }
            catch (Exception e)
            {
                Trace.WriteLine($"Encountered error while disposing powershell session: {e}");
            }
            PowerShell = null;

            try
            {
                Runspace?.Dispose();
            }
            catch (Exception e)
            {
                Trace.WriteLine($"Encountered error while disposing powershell runspace: {e}");
            }
            Runspace = null;
        }
Esempio n. 18
0
        private static void RunScript(string script, string[] args)
        {
            lock (psLocker)
            {
                powershellHost   = new Host();
                powershellEngine = System.Management.Automation.PowerShell.Create();
            }

            try
            {
                InitialSessionState initalState = InitialSessionState.CreateDefault();

                List <ParameterItem> validCmds = new List <ParameterItem>();
                //AddValidCommands

                Commandline cmdLine = new Commandline(args);

                if (cmdLine["help"] == "true" || cmdLine["?"] == "true")
                {
                    AssemblyData assInfo = new AssemblyData(System.Reflection.Assembly.GetExecutingAssembly());

                    StringBuilder outputBuilder = new StringBuilder();
                    outputBuilder.AppendLine();
                    outputBuilder.AppendLine(string.Format("{0} v{1} by {2}", assInfo.Product, assInfo.Version, assInfo.Company));
                    outputBuilder.AppendLine(assInfo.Copyright);
                    outputBuilder.AppendLine();
                    outputBuilder.AppendLine(" [-Help]");
                    outputBuilder.AppendLine("    Show help");

                    foreach (ParameterItem cmdName in validCmds)
                    {
                        if (cmdName.Mandatory)
                        {
                            outputBuilder.AppendLine(string.Format(" -{0} <{1}>", cmdName.Name, cmdName.Type));
                        }
                        else
                        {
                            outputBuilder.AppendLine(string.Format(" [-{0} <{1}>]", cmdName.Name, cmdName.Type));
                        }

                        if (!string.IsNullOrWhiteSpace(cmdName.HelpText))
                        {
                            outputBuilder.AppendLine(string.Format("    {0}", cmdName.HelpText));
                        }
                    }

                    if (hideCon)
                    {
                        MessageBox.Show(outputBuilder.ToString(), "Help", MessageBoxButtons.OK, MessageBoxIcon.Question);
                    }
                    else
                    {
                        ConsoleHandler.WriteLine(outputBuilder.ToString());
                    }

                    return;
                }

                Dictionary <string, object> cmdLineArgs = new Dictionary <string, object>();
                foreach (string arg in cmdLine.GetKeys())
                {
                    ParameterItem paramItem = validCmds.FirstOrDefault(x => String.Equals(x.Name, arg, StringComparison.CurrentCultureIgnoreCase));

                    if (paramItem != null)
                    {
                        try
                        {
                            object realItem;
                            switch (paramItem.Type)
                            {
                            case "sbyte":
                                realItem = sbyte.Parse(cmdLine[arg]);
                                break;

                            case "byte":
                                realItem = byte.Parse(cmdLine[arg]);
                                break;

                            case "short":
                                realItem = short.Parse(cmdLine[arg]);
                                break;

                            case "ushort":
                                realItem = ushort.Parse(cmdLine[arg]);
                                break;

                            case "int":
                                realItem = int.Parse(cmdLine[arg]);
                                break;

                            case "uint":
                                realItem = uint.Parse(cmdLine[arg]);
                                break;

                            case "ulong":
                                realItem = ulong.Parse(cmdLine[arg]);
                                break;

                            case "long":
                                realItem = long.Parse(cmdLine[arg]);
                                break;

                            case "float":
                                realItem = float.Parse(cmdLine[arg]);
                                break;

                            case "double":
                                realItem = double.Parse(cmdLine[arg]);
                                break;

                            case "decimal":
                                realItem = decimal.Parse(cmdLine[arg]);
                                break;

                            case "char":
                                realItem = char.Parse(cmdLine[arg]);
                                break;

                            case "switch":
                            case "bool":
                                realItem = bool.Parse(cmdLine[arg]);
                                break;

                            case "boolean":
                                realItem = Boolean.Parse(cmdLine[arg]);
                                break;

                            default:
                                realItem = cmdLine[arg];
                                break;
                            }

                            cmdLineArgs.Add(arg, realItem);
                        }
                        catch (Exception)
                        {
                            string errorString = string.Format("Parameter '-{0}' was not in correct format: '{1}'", arg, paramItem.Type);

                            if (hideCon)
                            {
                                MessageBox.Show(errorString, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }
                            else
                            {
                                ConsoleHandler.WriteLine(errorString);
                            }

                            return;
                        }
                    }
                    else
                    {
                        StringBuilder outputBuilder = new StringBuilder();
                        outputBuilder.AppendLine(string.Format("Parameter '-{0}' is not valid. Use '-help' to show valid parameters.", arg));

                        if (hideCon)
                        {
                            MessageBox.Show(outputBuilder.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                        else
                        {
                            ConsoleHandler.WriteLine(outputBuilder.ToString());
                        }

                        return;
                    }
                }

                foreach (ParameterItem paramItem in validCmds.Where(x => x.Mandatory == true))
                {
                    if (!cmdLineArgs.ContainsKey(paramItem.Name.ToLower()))
                    {
                        StringBuilder outputBuilder = new StringBuilder();
                        outputBuilder.AppendLine(string.Format("Parameter '-{0}' of type '{1}' is mandatory.", paramItem.Name, paramItem.Type));

                        if (hideCon)
                        {
                            MessageBox.Show(outputBuilder.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                        else
                        {
                            ConsoleHandler.WriteLine(outputBuilder.ToString());
                        }

                        return;
                    }
                }

                List <string> modulesToLoad = Common.ProcessManifest(initalState);

                powershellEngine.Runspace = RunspaceFactory.CreateRunspace(powershellHost, initalState);
                powershellEngine.Runspace.ApartmentState = System.Threading.ApartmentState.MTA;
                powershellEngine.Runspace.Open();

                RunspaceInvoke runSpaceInvoker = new RunspaceInvoke(powershellEngine.Runspace);

                try
                {
                    runSpaceInvoker.Invoke("Set-ExecutionPolicy Unrestricted -Scope Process");
                }
                catch
                {
                }

                foreach (string module in modulesToLoad)
                {
                    try
                    {
                        runSpaceInvoker.Invoke(string.Format("Import-Module {0} -Scope Global", module));
                    }
                    catch (Exception e)
                    {
                        ConsoleHandler.WriteLine(string.Format("Could import module {0}: {0}", e.Message, module));
                    }
                }

                Pipeline pipeline = powershellEngine.Runspace.CreatePipeline();
                Command  command  = new Command(script, true, true);

                foreach (KeyValuePair <string, object> cmdLineData in cmdLineArgs)
                {
                    command.Parameters.Add(cmdLineData.Key, cmdLineData.Value);
                }

                pipeline.Commands.Add(command);
                Collection <PSObject> resultObjects = pipeline.Invoke();

                foreach (PSObject resultObject in resultObjects)
                {
                    ConsoleHandler.WriteLine(resultObject.ToString());
                }
            }
            catch (Exception e)
            {
                ConsoleHandler.WriteLine(string.Format("Internal error: {0}", e.Message));
            }
            finally
            {
                lock (psLocker)
                {
                    powershellEngine.Dispose();
                    powershellEngine = null;
                }
            }
        }
Esempio n. 19
0
        /// <summary>
        /// A helper class that builds and executes a pipeline that writes to the
        /// default output path. Any exceptions that are thrown are just passed to
        /// the caller. Since all output goes to the default outter, this method()
        /// won't return anything.
        /// </summary>
        /// <param name="cmd">The script to run</param>
        /// <param name="input">Any input arguments to pass to the script. If null
        /// then nothing is passed in.</param>
        void executeHelper(string cmd, object input)
        {
            // Just ignore empty command lines...
            if (String.IsNullOrEmpty(cmd))
                return;

            // Create the pipeline object and make it available
            // to the ctrl-C handle through the currentPowerShell instance
            // variable

            lock (instanceLock)
            {
                currentPowerShell = PowerShell.Create();
            }

            currentPowerShell.Runspace = myRunSpace;

            // Create a pipeline for this execution - place the result in the currentPowerShell
            // instance variable so it is available to be stopped.
            try
            {
                currentPowerShell.AddScript(cmd);

                // Now add the default outputter to the end of the pipe and indicate
                // that it should handle both output and errors from the previous
                // commands. This will result in the output being written using the PSHost
                // and PSHostUserInterface classes instead of returning objects to the hosting
                // application.

                currentPowerShell.AddCommand("out-default");
                currentPowerShell.Commands.Commands[0].MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output);

                // If there was any input specified, pass it in, otherwise just
                // execute the pipeline...

                if (input != null)
                {
                    currentPowerShell.Invoke(new object[] { input });
                }
                else
                {
                    currentPowerShell.Invoke();
                }
            }
            finally
            {
                // Dispose of the pipeline line and set it to null, locked because currentPowerShell
                // may be accessed by the ctrl-C handler...
                lock (instanceLock)
                {
                    currentPowerShell.Dispose();
                    currentPowerShell = null;
                }
            }
        }
Esempio n. 20
0
 public virtual void TestCleanup()
 {
     powershell.Dispose();
 }
Esempio n. 21
0
        public static string GetHelpUri(PSObject commandInfoPSObject)
        {
            if (null == commandInfoPSObject)
            {
                return(string.Empty);
            }
            CommandInfo cmdInfo = PSObject.Base(commandInfoPSObject) as CommandInfo;

            // GetHelpUri helper method is expected to be used only by System.Management.Automation.CommandInfo
            // objects from types.ps1xml
            if ((null == cmdInfo) || (string.IsNullOrEmpty(cmdInfo.Name)))
            {
                return(string.Empty);
            }

            // The type checking is needed to avoid a try..catch exception block as
            // the CommandInfo.CommandMetadata throws an InvalidOperationException
            // instead of returning null.
            if ((cmdInfo is CmdletInfo) || (cmdInfo is FunctionInfo) ||
                (cmdInfo is ExternalScriptInfo) || (cmdInfo is ScriptInfo))
            {
                if (!string.IsNullOrEmpty(cmdInfo.CommandMetadata.HelpUri))
                {
                    return(cmdInfo.CommandMetadata.HelpUri);
                }
            }

            AliasInfo aliasInfo = cmdInfo as AliasInfo;

            if ((null != aliasInfo) &&
                (null != aliasInfo.ExternalCommandMetadata) &&
                (!string.IsNullOrEmpty(aliasInfo.ExternalCommandMetadata.HelpUri)))
            {
                return(aliasInfo.ExternalCommandMetadata.HelpUri);
            }

            // if everything else fails..depend on Get-Help infrastructure to get us the Uri.
            string cmdName = cmdInfo.Name;

            if (!string.IsNullOrEmpty(cmdInfo.ModuleName))
            {
                cmdName = string.Format(CultureInfo.InvariantCulture,
                                        "{0}\\{1}", cmdInfo.ModuleName, cmdInfo.Name);
            }

            if (DoesCurrentRunspaceIncludeCoreHelpCmdlet())
            {
                // Win8: 651300 if core get-help is present in the runspace (and it is the only get-help command), use
                // help system directly and avoid perf penalty.
                var currentContext = System.Management.Automation.Runspaces.LocalPipeline.GetExecutionContextFromTLS();
                if ((null != currentContext) && (null != currentContext.HelpSystem))
                {
                    HelpRequest helpRequest = new HelpRequest(cmdName, cmdInfo.HelpCategory);
                    helpRequest.ProviderContext = new ProviderContext(
                        string.Empty,
                        currentContext,
                        currentContext.SessionState.Path);
                    helpRequest.CommandOrigin = CommandOrigin.Runspace;
                    foreach (
                        Uri result in
                        currentContext.HelpSystem.ExactMatchHelp(helpRequest).Select(
                            helpInfo => helpInfo.GetUriForOnlineHelp()).Where(result => null != result))
                    {
                        return(result.OriginalString);
                    }
                }
            }
            else
            {
                // win8: 546025. Using Get-Help as command, instead of calling HelpSystem.ExactMatchHelp
                // for the following reasons:
                // 1. Exchange creates proxies for Get-Command and Get-Help in their scenario
                // 2. This method is primarily used to get uri faster while serializing the CommandInfo objects (from Get-Command)
                // 3. Exchange uses Get-Help proxy to not call Get-Help cmdlet at-all while serializing CommandInfo objects
                // 4. Using HelpSystem directly will not allow Get-Help proxy to do its job.
                System.Management.Automation.PowerShell getHelpPS = System.Management.Automation.PowerShell.Create(
                    RunspaceMode.CurrentRunspace).AddCommand("get-help").
                                                                    AddParameter("Name", cmdName).AddParameter("Category",
                                                                                                               cmdInfo.HelpCategory.ToString());
                try
                {
                    Collection <PSObject> helpInfos = getHelpPS.Invoke();

                    if (null != helpInfos)
                    {
                        for (int index = 0; index < helpInfos.Count; index++)
                        {
                            HelpInfo helpInfo;
                            if (LanguagePrimitives.TryConvertTo <HelpInfo>(helpInfos[index], out helpInfo))
                            {
                                Uri result = helpInfo.GetUriForOnlineHelp();
                                if (null != result)
                                {
                                    return(result.OriginalString);
                                }
                            }
                            else
                            {
                                Uri result = BaseCommandHelpInfo.GetUriFromCommandPSObject(helpInfos[index]);
                                return((result != null) ? result.OriginalString : string.Empty);
                            }
                        }
                    }
                }
                finally
                {
                    getHelpPS.Dispose();
                }
            }

            return(string.Empty);
        }
 public void IterationCleanup()
 {
     pwsh.Dispose();
 }
Esempio n. 23
0
        internal static PSKeyInfo ReadKey()
        {
            // Reading a key is handled on a different thread.  During process shutdown,
            // PowerShell will wait in it's ConsoleCtrlHandler until the pipeline has completed.
            // If we're running, we're most likely blocked waiting for user input.
            // This is a problem for two reasons.  First, exiting takes a long time (5 seconds
            // on Win8) because PowerShell is waiting forever, but the OS will forcibly terminate
            // the console.  Also - if there are any event handlers for the engine event
            // PowerShell.Exiting, those handlers won't get a chance to run.
            //
            // By waiting for a key on a different thread, our pipeline execution thread
            // (the thread ReadLine is called from) avoid being blocked in code that can't
            // be unblocked and instead blocks on events we control.

            // First, set an event so the thread to read a key actually attempts to read a key.
            _singleton._readKeyWaitHandle.Set();

            int handleId;

            System.Management.Automation.PowerShell ps = null;

            try
            {
                while (true)
                {
                    // Next, wait for one of three things:
                    //   - a key is pressed
                    //   - the console is exiting
                    //   - 300ms timeout - to process events if we're idle
                    //   - ReadLine cancellation is requested externally
                    handleId = WaitHandle.WaitAny(_singleton._requestKeyWaitHandles, 300);
                    if (handleId != WaitHandle.WaitTimeout)
                    {
                        break;
                    }

                    if (_handleIdleOverride is not null)
                    {
                        _handleIdleOverride(_singleton._cancelReadCancellationToken);
                        continue;
                    }

                    // If we timed out, check for event subscribers (which is just
                    // a hint that there might be an event waiting to be processed.)
                    var eventSubscribers = _singleton._engineIntrinsics?.Events.Subscribers;
                    if (eventSubscribers?.Count > 0)
                    {
                        bool runPipelineForEventProcessing = false;
                        foreach (var sub in eventSubscribers)
                        {
                            if (sub.SourceIdentifier.Equals(PSEngineEvent.OnIdle, StringComparison.OrdinalIgnoreCase))
                            {
                                // If the buffer is not empty, let's not consider we are idle because the user is in the middle of typing something.
                                if (_singleton._buffer.Length > 0)
                                {
                                    continue;
                                }

                                // There is an OnIdle event subscriber and we are idle because we timed out and the buffer is empty.
                                // Normally PowerShell generates this event, but PowerShell assumes the engine is not idle because
                                // it called PSConsoleHostReadLine which isn't returning. So we generate the event instead.
                                runPipelineForEventProcessing = true;
                                _singleton._engineIntrinsics.Events.GenerateEvent(PSEngineEvent.OnIdle, null, null, null);

                                // Break out so we don't genreate more than one 'OnIdle' event for a timeout.
                                break;
                            }

                            runPipelineForEventProcessing = true;
                        }

                        // If there are any event subscribers, run a tiny useless PowerShell pipeline
                        // so that the events can be processed.
                        if (runPipelineForEventProcessing)
                        {
                            if (ps == null)
                            {
                                ps = System.Management.Automation.PowerShell.Create(RunspaceMode.CurrentRunspace);
                                ps.AddScript("0", useLocalScope: true);
                            }

                            // To detect output during possible event processing, see if the cursor moved
                            // and rerender if so.
                            var console = _singleton._console;
                            var y       = console.CursorTop;
                            ps.Invoke();
                            if (y != console.CursorTop)
                            {
                                _singleton._initialY = console.CursorTop;
                                _singleton.Render();
                            }
                        }
                    }
                }
            }
            finally
            {
                ps?.Dispose();
            }

            if (handleId == ConsoleExiting)
            {
                // The console is exiting - throw an exception to unwind the stack to the point
                // where we can return from ReadLine.
                if (_singleton.Options.HistorySaveStyle == HistorySaveStyle.SaveAtExit)
                {
                    _singleton.SaveHistoryAtExit();
                }
                _singleton._historyFileMutex.Dispose();

                throw new OperationCanceledException();
            }

            if (handleId == CancellationRequested)
            {
                // ReadLine was cancelled. Save the current line to be restored next time ReadLine
                // is called, clear the buffer and throw an exception so we can return an empty string.
                _singleton.SaveCurrentLine();
                _singleton._getNextHistoryIndex = _singleton._history.Count;
                _singleton._current             = 0;
                _singleton._buffer.Clear();
                _singleton.Render();
                throw new OperationCanceledException();
            }

            var key = _singleton._queuedKeys.Dequeue();

            return(key);
        }
Esempio n. 24
0
        object IPSConsoleReadLineMockableMethods.GetDynamicHelpContent(string commandName, string parameterName, bool isFullHelp)
        {
            if (string.IsNullOrEmpty(commandName))
            {
                return(null);
            }

            System.Management.Automation.PowerShell ps = null;

            try
            {
                if (!_mockableMethods.RunspaceIsRemote(_runspace))
                {
                    ps = System.Management.Automation.PowerShell.Create(RunspaceMode.CurrentRunspace);
                }
                else
                {
                    ps          = System.Management.Automation.PowerShell.Create();
                    ps.Runspace = _runspace;
                }

                if (isFullHelp)
                {
                    return(ps
                           .AddCommand($"Microsoft.PowerShell.Core\\Get-Help")
                           .AddParameter("Name", commandName)
                           .AddParameter("Full", value: true)
                           .AddCommand($"Microsoft.PowerShell.Utility\\Out-String")
                           .Invoke <string>()
                           .FirstOrDefault());
                }

                if (string.IsNullOrEmpty(parameterName))
                {
                    return(null);
                }

                return(ps
                       .AddCommand("Microsoft.PowerShell.Core\\Get-Help")
                       .AddParameter("Name", commandName)
                       .AddParameter("Parameter", parameterName)
                       .Invoke <PSObject>()
                       .FirstOrDefault());
            }
            catch (Exception)
            {
                return(null);
            }
            finally
            {
                ps?.Dispose();

                // GetDynamicHelpContent could scroll the screen, e.g. via Write-Progress. For example,
                // Get-Help for unknown command under the CloudShell Azure drive will show the progress bar while searching for command.
                // We need to update the _initialY in case the current cursor postion has changed.
                if (_singleton._initialY > _console.CursorTop)
                {
                    _singleton._initialY = _console.CursorTop;
                }
            }
        }
Esempio n. 25
0
        private static ConsoleKeyInfo ReadKey()
        {
            // Reading a key is handled on a different thread.  During process shutdown,
            // PowerShell will wait in it's ConsoleCtrlHandler until the pipeline has completed.
            // If we're running, we're most likely blocked waiting for user input.
            // This is a problem for two reasons.  First, exiting takes a long time (5 seconds
            // on Win8) because PowerShell is waiting forever, but the OS will forcibly terminate
            // the console.  Also - if there are any event handlers for the engine event
            // PowerShell.Exiting, those handlers won't get a chance to run.
            //
            // By waiting for a key on a different thread, our pipeline execution thread
            // (the thread Readline is called from) avoid being blocked in code that can't
            // be unblocked and instead blocks on events we control.

            // First, set an event so the thread to read a key actually attempts to read a key.
            _singleton._readKeyWaitHandle.Set();

            int handleId;

            System.Management.Automation.PowerShell ps = null;

            try
            {
                while (true)
                {
                    // Next, wait for one of three things:
                    //   - a key is pressed
                    //   - the console is exiting
                    //   - 300ms - to process events if we're idle

                    handleId = WaitHandle.WaitAny(_singleton._requestKeyWaitHandles, 300);
                    if (handleId != WaitHandle.WaitTimeout)
                    {
                        break;
                    }
                    if (_singleton._engineIntrinsics == null)
                    {
                        continue;
                    }

                    // If we timed out, check for event subscribers (which is just
                    // a hint that there might be an event waiting to be processed.)
                    var eventSubscribers = _singleton._engineIntrinsics.Events.Subscribers;
                    if (eventSubscribers.Count > 0)
                    {
                        bool runPipelineForEventProcessing = false;
                        foreach (var sub in eventSubscribers)
                        {
                            if (sub.SourceIdentifier.Equals("PowerShell.OnIdle", StringComparison.OrdinalIgnoreCase))
                            {
                                // There is an OnIdle event.  We're idle because we timed out.  Normally
                                // PowerShell generates this event, but PowerShell assumes the engine is not
                                // idle because it called PSConsoleHostReadline which isn't returning.
                                // So we generate the event intstead.
                                _singleton._engineIntrinsics.Events.GenerateEvent("PowerShell.OnIdle", null, null, null);
                                runPipelineForEventProcessing = true;
                                break;
                            }

                            // If there are any event subscribers that have an action (which might
                            // write to the console) and have a source object (i.e. aren't engine
                            // events), run a tiny useless bit of PowerShell so that the events
                            // can be processed.
                            if (sub.Action != null && sub.SourceObject != null)
                            {
                                runPipelineForEventProcessing = true;
                                break;
                            }
                        }

                        if (runPipelineForEventProcessing)
                        {
                            if (ps == null)
                            {
                                ps = System.Management.Automation.PowerShell.Create(RunspaceMode.CurrentRunspace);
                                ps.AddScript("0");
                            }

                            // To detect output during possible event processing, see if the cursor moved
                            // and rerender if so.
                            var console = _singleton._console;
                            var y       = console.CursorTop;
                            ps.Invoke();
                            if (y != console.CursorTop)
                            {
                                _singleton._initialY = console.CursorTop;
                                _singleton.Render();
                            }
                        }
                    }
                }
            }
            finally
            {
                if (ps != null)
                {
                    ps.Dispose();
                }
            }

            if (handleId == 1)
            {
                // The console is exiting - throw an exception to unwind the stack to the point
                // where we can return from ReadLine.
                if (_singleton.Options.HistorySaveStyle == HistorySaveStyle.SaveAtExit)
                {
                    _singleton.SaveHistoryAtExit();
                }
                _singleton._historyFileMutex.Dispose();

                throw new OperationCanceledException();
            }

            var key = _singleton._queuedKeys.Dequeue();

            return(key);
        }
Esempio n. 26
0
 public void GlobalCleanup()
 {
     pwsh.Dispose();
 }