internal void GetNames(string[] path, ReturnContainers returnContainers, bool recurse, ProviderRuntime runtime) { // the include/exclude filters apply to the results, not to the globbing process. Make this sure runtime.IgnoreFiltersForGlobbing = true; // compile here, not in every recursive iteration var filter = new IncludeExcludeFilter(runtime.Include, runtime.Exclude, false); // do the globbing manually, because the behavior depends on it... foreach (var p in path) { CmdletProvider provider; var doGlob = Globber.ShouldGlob(p, runtime); // even if we don't actually glob, the next method will return the resolved path & provider var resolved = Globber.GetGlobbedProviderPaths(p, runtime, out provider); var contProvider = CmdletProvider.As <ContainerCmdletProvider>(provider); foreach (var curPath in resolved) { if (!doGlob && filter.CanBeIgnored && !recurse) { contProvider.GetChildNames(curPath, returnContainers, runtime); continue; } if ((recurse || !doGlob) && Item.IsContainer(contProvider, curPath, runtime)) { ManuallyGetChildNames(contProvider, curPath, "", returnContainers, recurse, filter, runtime); continue; } var cn = Path.ParseChildName(contProvider, curPath, runtime); if (filter.Accepts(cn)) { runtime.WriteObject(cn); } } } }
internal bool Exists(string path, ProviderRuntime runtime) { CmdletProvider provider; var globbedPaths = Globber.GetGlobbedProviderPaths(path, runtime, false, out provider); var itemProvider = provider as ItemCmdletProvider; // we assume that in a low level CmdletProvider all items exists. Not sure about this, but I don't want to // break existing functionality if (itemProvider == null) { return(true); } foreach (var p in globbedPaths) { var exists = false; try { exists = itemProvider.ItemExists(p, runtime); } catch (Exception e) { HandleCmdletProviderInvocationException(e); } if (exists) { return(true); } } return(false); }
private Collection <T> GlobAndCollect <T>(IList <string> paths, ProviderRuntime runtime, Func <string, IContentCmdletProvider, T> method) { var returnCollection = new Collection <T>(); foreach (var curPath in paths) { CmdletProvider provider; var globbedPaths = Globber.GetGlobbedProviderPaths(curPath, runtime, false, out provider); var contentProvider = CmdletProvider.As <IContentCmdletProvider>(provider); provider.ProviderRuntime = runtime; // make sure the runtime is set foreach (var p in globbedPaths) { try { returnCollection.Add(method(p, contentProvider)); } catch (Exception e) { HandleCmdletProviderInvocationException(e); } } } return(returnCollection); }
// actual work with callid the providers internal void Get(string[] paths, bool recurse, ProviderRuntime runtime) { // the include/exclude filters apply to the results, not to the globbing process. Make this sure runtime.IgnoreFiltersForGlobbing = true; // globbing is here a little more complicated, so we do it "manually" (without GlobAndInvoke) foreach (var curPath in paths) { var path = curPath; // if the path won't be globbed or filtered, we will directly list it's child var listChildsWithoutRecursion = !Globber.ShouldGlob(path, runtime) && !runtime.HasFilters(); // the Path might be a mixture of a path and an include filter bool clearIncludeFilter; path = SplitFilterFromPath(path, recurse, runtime, out clearIncludeFilter); // now perform the actual globbing CmdletProvider provider; var globbed = Globber.GetGlobbedProviderPaths(path, runtime, out provider); var containerProvider = CmdletProvider.As <ContainerCmdletProvider>(provider); var filter = new IncludeExcludeFilter(runtime.Include, runtime.Exclude, false); foreach (var globPath in globbed) { try { // if we need to actively filter that stuff, we have to handle the recursion manually if (!filter.CanBeIgnored) { ManuallyGetChildItems(containerProvider, globPath, recurse, filter, runtime); return; } // otherwise just get the child items / the item directly if (recurse || listChildsWithoutRecursion) { GetItemOrChildItems(containerProvider, globPath, recurse, runtime); return; } // no recursion and globbing was performed: get the item, not the child items containerProvider.GetItem(globPath, runtime); } catch (Exception e) { HandleCmdletProviderInvocationException(e); } } // clean up the include filter of the runtime for the next item, if we split a filter from the path if (clearIncludeFilter) { runtime.Include.Clear(); } } }
//internal Collection<string> GetResolvedProviderPathFromProviderPath(string path, string providerId, ProviderRuntime runtime); //internal Collection<string> GetResolvedProviderPathFromPSPath(string path, ProviderRuntime runtime); internal Collection <PathInfo> GetResolvedPSPathFromPSPath(string[] paths, ProviderRuntime runtime) { var resolved = new Collection <PathInfo>(); foreach (var path in paths) { CmdletProvider p; // by using always a fresh copy of the runtime, we make sure that different paths don't affect each other var runtimeCopy = new ProviderRuntime(runtime); var globbed = Globber.GetGlobbedProviderPaths(path, runtimeCopy, out p); foreach (var curPath in globbed) { resolved.Add(new PathInfo(runtimeCopy.PSDriveInfo, curPath, _sessionState)); } } return(resolved); }
internal bool IsContainer(string path, ProviderRuntime runtime) { CmdletProvider provider; var globbedPaths = Globber.GetGlobbedProviderPaths(path, runtime, false, out provider); var containerProvider = provider as ContainerCmdletProvider; var isNavProvider = provider is NavigationCmdletProvider; if (containerProvider == null && !isNavProvider) { throw new NotSupportedException("The affected provider doesn't support container related operations."); } foreach (var p in globbedPaths) { if (!IsContainer(containerProvider, p, runtime)) { return(false); } } // all globbed paths are containers return(true); }
internal void New(string[] paths, string name, string type, object content, ProviderRuntime runtime) { var validName = !String.IsNullOrEmpty(name); CmdletProvider provider; foreach (var path in paths) { Collection <string> resolvedPaths; // only allow globbing if name is used. otherwise it doesn't make sense if (validName) { resolvedPaths = Globber.GetGlobbedProviderPaths(path, runtime, false, out provider); } else { ProviderInfo providerInfo; resolvedPaths = new Collection <string>(); resolvedPaths.Add(Globber.GetProviderSpecificPath(path, runtime, out providerInfo)); provider = SessionState.Provider.GetInstance(providerInfo); } var containerProvider = CmdletProvider.As <ContainerCmdletProvider>(provider); foreach (var curResolvedPath in resolvedPaths) { var resPath = curResolvedPath; if (validName) { resPath = Path.Combine(containerProvider, resPath, name, runtime); } try { containerProvider.NewItem(resPath, type, content, runtime); } catch (Exception e) { HandleCmdletProviderInvocationException(e); } } } }
internal void Rename(string path, string newName, ProviderRuntime runtime) { CmdletProvider provider; var globbed = Globber.GetGlobbedProviderPaths(path, runtime, out provider); if (globbed.Count != 1) { throw new PSArgumentException("Cannot rename more than one item", "MultipleItemsRename", ErrorCategory.InvalidArgument); } path = globbed[0]; var containerProvider = CmdletProvider.As <ContainerCmdletProvider>(provider); // TODO: I think Powershell checks whether we are currently in the path we want to remove // (or a subpath). Check this and throw an error if it's true try { containerProvider.RenameItem(path, newName, runtime); } catch (Exception e) { HandleCmdletProviderInvocationException(e); } }
internal void Clear(string[] path, ProviderRuntime runtime) { foreach (var curPath in path) { CmdletProvider provider; var globbedPaths = Globber.GetGlobbedProviderPaths(curPath, runtime, false, out provider); var contentProvider = CmdletProvider.As <IContentCmdletProvider>(provider); provider.ProviderRuntime = runtime; // make sure the runtime is set! foreach (var p in globbedPaths) { try { if (Item.Exists(p, runtime)) { contentProvider.ClearContent(p); } } catch (Exception e) { HandleCmdletProviderInvocationException(e); } } } }