/// <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; } }
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()); }
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 nodes = PSScriptRunner.InvokeScriptBlock(context, item, _drive)?.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); } } }
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); }
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); }