private IFileOperation InitOperation(Uri uri, ResourceOperation operation, object arg, FileOperationProgressSink sink) { IShellItem source = null, target = null; string name = null; FileAttributes attributes = 0; IPropertyChangeArray properties = null; switch (operation) { case ResourceOperation.Create: attributes = (FileAttributes)arg; name = HttpUtility.UrlDecode(uri.Segments[uri.Segments.Length - 1]); uri = new Uri(uri, "."); source = GetItem(uri); break; case ResourceOperation.Delete: source = GetItem(uri); break; case ResourceOperation.Move: source = GetItem(uri); name = arg as string; if (name == null) { uri = (Uri)arg; name = HttpUtility.UrlDecode(uri.Segments[uri.Segments.Length - 1]); uri = new Uri(uri, "."); target = GetItem(uri); } break; case ResourceOperation.Copy: source = GetItem(uri); uri = (Uri)arg; name = HttpUtility.UrlDecode(uri.Segments[uri.Segments.Length - 1]); uri = new Uri(uri, "."); target = GetItem(uri); break; default: throw new NotImplementedException(); } return(CreateOperation(operation, source, target, name, attributes, properties, sink)); }
// todo: to encapsulate /// <summary> /// Declares a set of properties and values to be set on an item or items. /// </summary> /// <param name="pproparray">An <see cref="IPropertyChangeArray"/>, which accesses a collection of <see cref="IPropertyChange"/> objects that specify the properties to be set and their new values.</param> /// <remarks>This method does not set the new property values, it merely declares them. To set property values on an item or a group of items, you must make at least the sequence of calls detailed here: /// <ol><li>Call <see cref="SetProperties"/> to declare the specific properties to be set and their new values.</li> /// <li>Call <see cref="ApplyPropertiesToItem(ShellObject)"/> or <see cref="ApplyPropertiesToItem(IShellItem)"/> to declare the item or items whose properties are to be set.</li> /// <li>Call <see cref="PerformOperations"/> to apply the properties to the item or items.</li></ol></remarks> /// <exception cref="ArgumentNullException">Exception thrown when a parameter is null.</exception> /// <exception cref="ObjectDisposedException">Exception thrown when this object is disposed.</exception> /// <exception cref="Win32Exception">Exception thrown when this method fails because of an error in the Win32 COM API implementation.</exception> public void SetProperties(IPropertyChangeArray pproparray) { if (pproparray == null) { throw new ArgumentNullException(nameof(pproparray)); } if (disposed) { throw new ObjectDisposedException(nameof(FileOperation)); } HResult hr = fileOperation.SetProperties(pproparray); if (!CoreErrorHelper.Succeeded(hr)) { Marshal.ThrowExceptionForHR((int)hr); } }
public static extern HRESULT PSCreatePropertyChangeArray( [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] PROPERTYKEY[] rgpropkey, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] PKA_FLAGS[] rgflags, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] PROPVARIANT[] rgpropvar, uint cChanges, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IPropertyChangeArray ppv);
public static T GetAt <T>(this IPropertyChangeArray pproparray, int iIndex) where T : class { return((T)pproparray.GetAt(iIndex, typeof(T).GUID)); }
private IFileOperation CreateOperation(ResourceOperation operation, IShellItem source, IShellItem target, string name, FileAttributes attributes, IPropertyChangeArray properties, FileOperationProgressSink sink) { var op = Shell32.CreateFileOperation(); op.Advise(sink); op.SetOwnerWindow(OwnerHwnd); op.SetOperationFlags(0x0400 | 0x0004 | 0x0200 | 0x00100000); switch (operation) { case ResourceOperation.Create: op.NewItem(source, attributes, name, null, null); break; case ResourceOperation.Delete: op.DeleteItem(source, null); break; case ResourceOperation.Move: if (target == null) { op.RenameItem(source, name, null); } else { op.MoveItem(source, target, name, null); } break; case ResourceOperation.Copy: op.CopyItem(source, target, name, null); break; } return(op); }