Example #1
0
        /// <summary>
        /// Closes the stream.
        /// </summary>
        public void Close()
        {
            if (_writer == null || _stream == null)
            {
                return;
            }

            try
            {
                _writer.Flush();
                _stream.Flush();

                // By now the PS engine completes reading from its pipleline and have the stream ready for SetConent()
                _stream.Seek(0, SeekOrigin.Begin);

                using (var reader = new StreamReader(_stream))
                {
                    // Read the entire content from the stream as a string text
                    var content = reader.ReadToEnd();
                    // Invoke SetContent and pass in content and path to the script
                    // Calling SHiPS based PowerShell provider '[object] SetContent([string]$content, [string]$path)'
                    var script = Constants.ScriptBlockWithParam3.StringFormat(Constants.SetContent);
                    PSScriptRunner.InvokeScriptBlock(_context, _node, _drive, script, PSScriptRunner.SetContentNotSupported, content, _context.Path);
                }
            }
            finally
            {
                _writer.Dispose();
                _stream.Dispose();

                _writer = null;
                _stream = null;
            }
        }
Example #2
0
        private object GetNodeChildrenDynamicParameters(SHiPSDirectory node)
        {
            var script     = Constants.ScriptBlockWithParam1.StringFormat(Constants.GetChildItemDynamicParameters);
            var parameters = PSScriptRunner.InvokeScriptBlock(null, node, _drive, script, PSScriptRunner.ReportErrors);

            return(parameters?.FirstOrDefault());
        }
Example #3
0
        private IEnumerable <IPathNode> GetNodeChildrenInternal(IProviderContext context)
        {
            //find the current parent node
            var item = this.ContainerNode;

            if (item == null || item.IsLeaf)
            {
                // WriteChildItem()/P2F can call us while 'dir -recurse' even if the node is set to leaflet.
                yield break;
            }

            // Set the ProviderContext as the DynamicParameters and Filter objects will be used in the
            // PowerShell module's GetChildItem().
            // If dynamic parameters are used, then SHiPS is not using cache.
            // ProviderContext has to be set right now because context.NeedRefresh uses it.
            item.SHiPSProviderContext.Set(context);

            // The item is the parent node from where we can find its child node list.
            // We will find child nodes from the cache if GetChildItem() has been called already and NeedRefresh is false.
            // Otherwise, we will execute the scriptblock and then add the returned nodes to item's child list
            if (item.UseCache && item.ItemNavigated && !context.NeedRefresh(item, _drive))
            {
                var list = item.Children.Values.SelectMany(each => each);

                foreach (var node in list)
                {
                    // Making sure to obey the StopProcessing.
                    if (context.Stopping)
                    {
                        yield break;
                    }
                    yield return(node);
                }
            }
            else
            {
                var script = Constants.ScriptBlockWithParam1.StringFormat(Constants.GetChildItem);
                var nodes  = PSScriptRunner.InvokeScriptBlockAndBuildTree(context, item, _drive, script, PSScriptRunner.ReportErrors)?.ToList();

                // Save the info of the node just visisted
                SHiPSProvider.LastVisisted.Set(context.Path, this, nodes);

                if (nodes == null || nodes.Count == 0)
                {
                    yield break;
                }

                foreach (var node in nodes)
                {
                    // Making sure to obey the StopProcessing.
                    if (context.Stopping)
                    {
                        yield break;
                    }
                    yield return(node);
                }
            }
        }
Example #4
0
        public IContentReader GetContentReader(IProviderContext context)
        {
            // Calling GetContent()
            var script  = Constants.ScriptBlockWithParam1.StringFormat(Constants.GetContent);
            var results = PSScriptRunner.InvokeScriptBlock(context, _node, _drive, script, PSScriptRunner.ReportErrors);

            // Expected a collection of strings returned from GetContent() and save it to a stream
            var stream = new ContentReader(results, context);

            return(stream);
        }
Example #5
0
        private object GetNodeChildrenDynamicParameters(string methodName, SHiPSDirectory node)
        {
            var errors = new ConcurrentBag <ErrorRecord>();

            var parameters = PSScriptRunner.CallPowerShellScript(
                node,
                null,
                _drive.PowerShellInstance,
                null,
                methodName,
                PSScriptRunner.output_DataAdded,
                (sender, e) => PSScriptRunner.error_DataAdded(sender, e, errors));

            if (errors.WhereNotNull().Any())
            {
                var error   = errors.FirstOrDefault();
                var message = Environment.NewLine;
                message += error.ErrorDetails == null ? error.Exception.Message : error.ErrorDetails.Message;
                throw new InvalidDataException(message);
            }

            return(parameters != null?parameters.FirstOrDefault() : null);
        }
Example #6
0
        private void InitializeRoot()
        {
            // Module.Type
            Match match = ModuleAndTypeRegex.Match(_rootInfo);

            if (!match.Success)
            {
                // Handling a case like: myModule#Test\FamilyTree#Austin
                match = TryExcludeFQProviderPath(_rootInfo);
                if (match == null)
                {
                    _provider.ThrowError(Resources.Resource.InvalidRootFormat.StringFormat(_rootInfo), ErrorId.InvalidRootFormat);
                    return;
                }
            }

            //first we need to make sure the module is loaded
            var moduleCommand = "import-module {0}; get-module {0} -verbose".StringFormat(match.Groups[1],
                                                                                          match.Groups[1]);

            _provider.WriteVerbose(moduleCommand);


            //get the module
            var module = _provider.SessionState.InvokeCommand.InvokeScript(moduleCommand, null).FirstOrDefault();

            if (module == null || !(module.BaseObject is PSModuleInfo))
            {
                // The reason that not using _provider.WriteError() here is because it is not terminatoring process
                // at this time, mearning the drive is actually gets created but not usable.
                //_provider.WriteError()
                _provider.ThrowError(Resources.Resource.CannotGetModule.StringFormat(match.Groups[1]), ErrorId.CannotGetModule);
                return;
            }

            //create powershell instance and load the modules currently referenced
            var moduleBaseObj = (PSModuleInfo)module.BaseObject;
            var modulePath    = Path.Combine((moduleBaseObj).ModuleBase, (moduleBaseObj).Name.TrimEnd() + ".psd1");

            if (!File.Exists(modulePath))
            {
                _provider.WriteWarning(Resources.Resource.FileNotExist.StringFormat(modulePath));
                modulePath = moduleBaseObj.Path;
                _provider.WriteWarning(Resources.Resource.Trying.StringFormat(modulePath));
            }

            _provider.WriteVerbose(modulePath);

            //create the instance of root module
            var createRootInstance = string.Format(CultureInfo.InvariantCulture,
                                                   @"using module '{0}'; $mod=get-module {1}; &($mod){{[{2}]::new('{2}')}}", modulePath, match.Groups[1], match.Groups[2]);

            _provider.WriteVerbose(createRootInstance);

            //ifdef #newrunspace
            PowerShellInstance = CreatePowerShellObject(_provider.Host, modulePath);
            PowerShellInstance.AddScript(createRootInstance);

            var errors = new ConcurrentBag <ErrorRecord>();

            var rootPsObject = PSScriptRunner.CallPowerShellScript(createRootInstance, PowerShellInstance, (sender, e) => PSScriptRunner.error_DataAdded(sender, e, errors));

            //var rootPsObject = PowerShellInstance.Invoke().FirstOrDefault();
            if (rootPsObject == null || !rootPsObject.Any())
            {
                var message = Resources.Resource.CannotCreateInstance.StringFormat(match.Groups[2], modulePath, match.Groups[2], match.Groups[2]);
                if (errors.WhereNotNull().Any())
                {
                    var error = errors.FirstOrDefault();
                    message += Environment.NewLine;
                    message += error.ErrorDetails == null ? error.Exception.Message : error.ErrorDetails.Message;
                }

                _provider.ThrowError(message, ErrorId.CannotCreateInstance);

                return;
            }

            var node = rootPsObject.FirstOrDefault().ToNode();

            if (node == null)
            {
                _provider.ThrowError(Resources.Resource.InvalidRootNode, ErrorId.NotContainerNode);
            }

            if (string.IsNullOrWhiteSpace(node.Name))
            {
                _provider.ThrowError(Resources.Resource.NameWithNullOrEmpty.StringFormat(string.IsNullOrWhiteSpace(node.Name) ? "root" : node.Name), ErrorId.NodeNameIsNullOrEmpty);
            }

            if (node.IsLeaf)
            {
                _provider.ThrowError(Resources.Resource.InvalidRootNodeType.StringFormat(Constants.Leaf), ErrorId.RootNodeTypeMustBeContainer);
            }

            RootNode = node;

            RootPathNode = new ContainerNodeService(this, node, null);

            // Getting the Get-ChildItem default parameters before running any commands. It will be used for checking
            // whether a user is passing in any dynamic parameters.
            _getChildItemDefaultParameters = GetChildItemDefaultParameters;
        }
Example #7
0
        private IPathNode GetNodeObjectFromPath(IProviderContext context, ContainerNodeService parent, string pathName, bool force)
        {
            var parentNode = parent?.ContainerNode;

            if (parentNode == null)
            {
                return(null);
            }

            // Check if the node has been dir'ed
            // Here we do not need to add NeedRefresh check because:
            // For cd (set-location), there is no -force, i.e., NeedRefresh is always false. This means for cached cases,
            // a user needs to do 'dir -force' to get fresh data.
            // For dir case, path in ResolvePath() is pointing to the parent path, e.g., dir c:\foo\bar\baz.txt,
            // the path is poing to c:\foo\bar even if baz.txt just gets created. Thus ResolvePath() only needs to resolve
            // the parent path and the GetChildItem() will check NeedRefresh to get fresh data.
            if (!force && parentNode.UseCache && parentNode.ItemNavigated)
            {
                var nodes = parentNode.Children.Where(each => pathName.EqualsIgnoreCase(each.Key)).Select(item => item.Value)
                            .FirstOrDefault();

                if (nodes != null && nodes.Any())
                {
                    return(nodes.FirstOrDefault());
                }
                else
                {
                    // If a childitem exists and cached, but none of them matches what specified in the 'pathName',
                    // we will return null, because
                    //
                    // dir         --- Assuming displays a long list of child items. So user does
                    // dir a[tab]  --- a user wants to see any child items start with 'a'. This may be no child item starts with a.
                    //                 so we do not need to go out fetching again if cache misses.
                    //
                    // caveat:
                    // dir foobar  --- if a user expects foobar child item exists, and cache misses, SHiPS is not going out fetch
                    //                 automatically, unless -force
                    // By removing the else block, SHiPS will go out fetching for data if cache misses. But dir a[tab] will be slow.
                    return(null);
                }
            }

            var children = PSScriptRunner.InvokeScriptBlock(context, parentNode, _drive)?.ToList();

            if (children == null)
            {
                return(null);
            }

            foreach (var node in children)
            {
                // Making sure to obey the StopProcessing.
                if (context.Stopping)
                {
                    return(null);
                }

                //add it to its child list
                if (node != null)
                {
                    if (pathName.EqualsIgnoreCase(node.Name))
                    {
                        return(node);
                    }
                }
            }
            return(null);
        }