internal Collection<string> GetGlobbedProviderPaths(string path, ProviderRuntime runtime, bool itemMustExist, out CmdletProvider provider) { var results = new Collection<string>(); ProviderInfo providerInfo; // get internal path, resolve home path and set provider info and drive info (if resolved) path = GetProviderSpecificPath(path, runtime, out providerInfo); provider = _sessionState.Provider.GetInstance(providerInfo); if (!ShouldGlob(path, runtime)) { // Although even ItemCmdletProvider supports ItemExists, PS doesn't seem // to throw errors when resolving paths with ItemProviders, only for ContainerProviders or higher // this behavior can be seen in the tests var containerProvider = provider as ContainerCmdletProvider; if (itemMustExist && containerProvider != null && !containerProvider.ItemExists(path, runtime)) { var msg = String.Format("An item with path {0} doesn't exist", path); runtime.WriteError(new ItemNotFoundException(msg).ErrorRecord); return results; } results.Add(path); return results; } if (providerInfo.Capabilities.HasFlag(ProviderCapabilities.ExpandWildcards)) { var filter = new IncludeExcludeFilter(runtime.Include, runtime.Exclude, runtime.IgnoreFiltersForGlobbing); foreach (var expanded in CmdletProvider.As<ItemCmdletProvider>(provider).ExpandPath(path, runtime)) { if (filter.Accepts(expanded)) { results.Add(expanded); } } } else { results = BuiltInGlobbing(provider, path, runtime); } return results; }
internal Collection <string> GetGlobbedProviderPaths(string path, ProviderRuntime runtime, bool itemMustExist, out CmdletProvider provider) { var results = new Collection <string>(); ProviderInfo providerInfo; // get internal path, resolve home path and set provider info and drive info (if resolved) path = GetProviderSpecificPath(path, runtime, out providerInfo); provider = _sessionState.Provider.GetInstance(providerInfo); if (!ShouldGlob(path, runtime)) { // Although even ItemCmdletProvider supports ItemExists, PS doesn't seem // to throw errors when resolving paths with ItemProviders, only for ContainerProviders or higher // this behavior can be seen in the tests var containerProvider = provider as ContainerCmdletProvider; if (itemMustExist && containerProvider != null && !containerProvider.ItemExists(path, runtime)) { var msg = String.Format("An item with path {0} doesn't exist", path); runtime.WriteError(new ItemNotFoundException(msg).ErrorRecord); return(results); } results.Add(path); return(results); } if (providerInfo.Capabilities.HasFlag(ProviderCapabilities.ExpandWildcards)) { var filter = new IncludeExcludeFilter(runtime.Include, runtime.Exclude, runtime.IgnoreFiltersForGlobbing); foreach (var expanded in CmdletProvider.As <ItemCmdletProvider>(provider).ExpandPath(path, runtime)) { if (filter.Accepts(expanded)) { results.Add(expanded); } } } else { results = BuiltInGlobbing(provider, path, runtime); } return(results); }
void CopyContainerToContainer(ContainerCmdletProvider provider, string srcPath, string destPath, bool recurse, CopyContainers copyContainers, ProviderRuntime runtime) { // the "usual" case: if we don't use recursion (empty container is copied) or we want to maintain the // original hierarchy if (!recurse || copyContainers.Equals(CopyContainers.CopyTargetContainer)) { provider.CopyItem(srcPath, destPath, recurse, runtime); return; } // Otherwise we want a flat-hierachy copy of a folder (because copyContainers is CopyChildrenOfTargetContainer) // Make sure recurse is set if (!recurse) { var error = new PSArgumentException("Cannot copy container to existing leaf", "CopyContainerItemToLeafError", ErrorCategory.InvalidArgument).ErrorRecord; runtime.WriteError(error); return; } // otherwise do the flat copy. To do this: get all child names (recursively) and invoke copying without recursion var childNames = ChildItem.GetNames(srcPath, ReturnContainers.ReturnMatchingContainers, true); foreach (var child in childNames) { var childPath = Path.Combine(provider, srcPath, child, runtime); provider.CopyItem(childPath, destPath, false, runtime); } }
internal void Move(string[] path, string destinationPath, ProviderRuntime runtime) { ProviderInfo destinationProvider; var destination = Globber.GetProviderSpecificPath(destinationPath, runtime, out destinationProvider); GlobAndInvoke<NavigationCmdletProvider>(path, runtime, (curPath, 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 if (!runtime.PSDriveInfo.Provider.Equals(destinationProvider)) { var msg = "The source cannot be moved to the destination, because they're not from the same provider"; var error = new PSArgumentException(msg, "MoveItemSourceAndDestinationNotSameProvider", ErrorCategory.InvalidArgument); runtime.WriteError(error.ErrorRecord); return; } provider.MoveItem(curPath, destination, runtime); } ); }
internal void Copy(string[] path, string destinationPath, bool recurse, CopyContainers copyContainers, ProviderRuntime runtime) { ProviderInfo destinationProvider; var destRuntime = new ProviderRuntime(runtime); var destination = Globber.GetProviderSpecificPath(destinationPath, destRuntime, out destinationProvider); // make sure we don't use the version of IsContainer that globs, or we will have unnecessary provider callbacks var destProvider = destinationProvider.CreateInstance() as ContainerCmdletProvider; // it's okay to be null var destIsContainer = IsContainer(destProvider, destination, destRuntime); GlobAndInvoke<ContainerCmdletProvider>(path, runtime, (curPath, provider) => { if (!runtime.PSDriveInfo.Provider.Equals(destinationProvider)) { var msg = "The source cannot be copied to the destination, because they're not from the same provider"; var error = new PSArgumentException(msg, "CopyItemSourceAndDestinationNotSameProvider", ErrorCategory.InvalidArgument); runtime.WriteError(error.ErrorRecord); return; } // Affected by #trailingSeparatorAmbiguity // PS would make sure the trailing slash of curPath is removed // check if src is a container if (IsContainer(provider, curPath, runtime)) { // if we copy a container to another, invoke a special method for this if (destIsContainer) { CopyContainerToContainer(provider, curPath, destination, recurse, copyContainers, runtime); return; } // otherwise the destination doesn't exist or is a leaf. Copying a container to a leaf doesn't work if (Exists(destination, destRuntime)) { var error = new PSArgumentException("Cannot copy container to existing leaf", "CopyContainerItemToLeafError", ErrorCategory.InvalidArgument).ErrorRecord; runtime.WriteError(error); return; } // otherwise we just proceed as normal } // either leaf to leaf, leaf to container, or container to not-existing (i.e. copy the container) provider.CopyItem(curPath, destination, recurse, runtime); } ); }