Пример #1
0
        private void HookupHostDataDelegates(ThreadJobHost host)
        {
            ThreadJobHostUI hostUI = host.UI as ThreadJobHostUI;

            System.Diagnostics.Debug.Assert(hostUI != null, "Host UI cannot be null.");

            hostUI.Output.DataAdded += (sender, dataAddedEventArgs) =>
            {
                Collection <PSObject> output = hostUI.Output.ReadAll();
                foreach (var item in output)
                {
                    _output.Add(item);
                }
            };

            hostUI.Error.DataAdded += (sender, dataAddedEventArgs) =>
            {
                Collection <ErrorRecord> error = hostUI.Error.ReadAll();
                foreach (var item in error)
                {
                    Error.Add(item);
                }
            };
        }
Пример #2
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="name"></param>
        /// <param name="command"></param>
        /// <param name="sb"></param>
        /// <param name="filePath"></param>
        /// <param name="initSb"></param>
        /// <param name="argumentList"></param>
        /// <param name="inputObject"></param>
        /// <param name="psCmdlet"></param>
        public ThreadJob(
            string name,
            string command,
            ScriptBlock sb,
            string filePath,
            ScriptBlock initSb,
            object[] argumentList,
            PSObject inputObject,
            PSCmdlet psCmdlet)
            : base(command, name)
        {
            _sb           = sb;
            _filePath     = filePath;
            _initSb       = initSb;
            _argumentList = argumentList;
            _input        = new PSDataCollection <object>();
            if (inputObject != null)
            {
                _input.Add(inputObject);
            }
            _output = new PSDataCollection <PSObject>();

            this.PSJobTypeName = "ThreadJob";

            // Create host object for thread jobs.
            ThreadJobHost host = new ThreadJobHost();

            HookupHostDataDelegates(host);

            // Create Runspace/PowerShell object and state callback.
            // The job script/command will run in a separate thread associated with the Runspace.
            _rs          = RunspaceFactory.CreateRunspace(host);
            _ps          = PowerShell.Create();
            _ps.Runspace = _rs;
            _ps.InvocationStateChanged += (sender, psStateChanged) =>
            {
                var newStateInfo = psStateChanged.InvocationStateInfo;

                // Update Job state.
                switch (newStateInfo.State)
                {
                case PSInvocationState.Running:
                    SetJobState(JobState.Running);
                    break;

                case PSInvocationState.Stopped:
                    SetJobState(JobState.Stopped, newStateInfo.Reason, disposeRunspace: true);
                    break;

                case PSInvocationState.Failed:
                    SetJobState(JobState.Failed, newStateInfo.Reason, disposeRunspace: true);
                    break;

                case PSInvocationState.Completed:
                    if (_runningInitScript)
                    {
                        // Begin running main script.
                        _runningInitScript = false;
                        RunScript();
                    }
                    else
                    {
                        SetJobState(JobState.Completed, newStateInfo.Reason, disposeRunspace: true);
                    }
                    break;
                }
            };

            // Get script block to run.
            if (!string.IsNullOrEmpty(_filePath))
            {
                _sb = GetScriptBlockFromFile(_filePath, psCmdlet);
                if (_sb == null)
                {
                    throw new InvalidOperationException(Properties.Resources.ResourceManager.GetString("CannotParseScriptFile"));
                }
            }
            else if (_sb == null)
            {
                throw new PSArgumentNullException(Properties.Resources.ResourceManager.GetString("NoScriptToRun"));
            }

            // Get any using variables.
            var usingAsts = _sb.Ast.FindAll(ast => ast is UsingExpressionAst, searchNestedScriptBlocks: true).Cast <UsingExpressionAst>();

            if (usingAsts != null &&
                usingAsts.FirstOrDefault() != null)
            {
                // Get using variables as an array or dictionary, depending on PowerShell version.
                if (psCmdlet.Host.Version.Major >= 5)
                {
                    _usingValuesMap = GetUsingValuesAsDictionary(usingAsts, psCmdlet);
                }
                else if (psCmdlet.Host.Version.Major == 3 || psCmdlet.Host.Version.Major == 4)
                {
                    _usingValuesArray = GetUsingValuesAsArray(usingAsts, psCmdlet);
                }
            }

            // Hook up data streams.
            this.Output = _output;
            this.Output.EnumeratorNeverBlocks = true;

            this.Error = _ps.Streams.Error;
            this.Error.EnumeratorNeverBlocks = true;

            this.Progress = _ps.Streams.Progress;
            this.Progress.EnumeratorNeverBlocks = true;

            this.Verbose = _ps.Streams.Verbose;
            this.Verbose.EnumeratorNeverBlocks = true;

            this.Warning = _ps.Streams.Warning;
            this.Warning.EnumeratorNeverBlocks = true;

            this.Debug = _ps.Streams.Debug;
            this.Debug.EnumeratorNeverBlocks = true;

            // Create the JobManager job definition and job specification, and add to the JobManager.
            ThreadJobDefinition = new JobDefinition(typeof(ThreadJobSourceAdapter), "", Name);
            Dictionary <string, object> parameterCollection = new Dictionary <string, object>();

            parameterCollection.Add("NewJob", this);
            var jobSpecification = new JobInvocationInfo(ThreadJobDefinition, parameterCollection);
            var newJob           = psCmdlet.JobManager.NewJob(jobSpecification);

            System.Diagnostics.Debug.Assert(newJob == this, "JobManager must return this job");
        }
Пример #3
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="name"></param>
        /// <param name="command"></param>
        /// <param name="sb"></param>
        /// <param name="filePath"></param>
        /// <param name="initSb"></param>
        /// <param name="argumentList"></param>
        /// <param name="inputObject"></param>
        /// <param name="psCmdlet"></param>
        public ThreadJob(
            string name,
            string command,
            ScriptBlock sb,
            string filePath,
            ScriptBlock initSb,
            object[] argumentList,
            PSObject inputObject,
            PSCmdlet psCmdlet)
            : base(command, name)
        {
            _sb           = sb;
            _filePath     = filePath;
            _initSb       = initSb;
            _argumentList = argumentList;
            _input        = new PSDataCollection <object>();
            if (inputObject != null)
            {
                _input.Add(inputObject);
            }
            _output = new PSDataCollection <PSObject>();

            this.PSJobTypeName = "ThreadJob";

            // Create host object for thread jobs.
            ThreadJobHost host = new ThreadJobHost();

            HookupHostDataDelegates(host);

            // Create Runspace/PowerShell object and state callback.
            // The job script/command will run in a separate thread associated with the Runspace.
            _rs = RunspaceFactory.CreateRunspace(host);
            _rs.Open();
            _ps          = PowerShell.Create();
            _ps.Runspace = _rs;
            _ps.InvocationStateChanged += (sender, psStateChanged) =>
            {
                // Update Job state.
                switch (psStateChanged.InvocationStateInfo.State)
                {
                case PSInvocationState.Running:
                    SetJobState(JobState.Running);
                    break;

                case PSInvocationState.Stopped:
                    SetJobState(JobState.Stopped);
                    break;

                case PSInvocationState.Failed:
                    SetJobState(JobState.Failed);
                    break;

                case PSInvocationState.Completed:
                    if (_runningInitScript)
                    {
                        // Begin running main script.
                        _runningInitScript = false;
                        RunScript();
                    }
                    else
                    {
                        SetJobState(JobState.Completed);
                    }
                    break;
                }
            };

            // Hook up data streams.
            this.Output = _output;
            this.Output.EnumeratorNeverBlocks = true;

            this.Error = _ps.Streams.Error;
            this.Error.EnumeratorNeverBlocks = true;

            this.Progress = _ps.Streams.Progress;
            this.Progress.EnumeratorNeverBlocks = true;

            this.Verbose = _ps.Streams.Verbose;
            this.Verbose.EnumeratorNeverBlocks = true;

            this.Warning = _ps.Streams.Warning;
            this.Warning.EnumeratorNeverBlocks = true;

            this.Debug = _ps.Streams.Debug;
            this.Debug.EnumeratorNeverBlocks = true;

            // Add to job repository
            if (psCmdlet != null)
            {
                psCmdlet.JobRepository.Add(this);
            }
        }