private void OnRemove(ShellOperationEventArgs e)
        {
            if (e.Item.IsFolder)
            {
                // delete a key
                using (var key = OpenKey(true))
                {
                    if (key != null)
                    {
                        key.DeleteSubKeyTree(e.Item.DisplayName, false);
                    }
                }
                e.HResult = ShellUtilities.S_OK;
                return;
            }

            // delete a value
            using (var key = OpenKey(true))
            {
                if (key != null)
                {
                    var keyName = ((RegistryValueItem)e.Item).KeyName;
                    key.DeleteValue(keyName, false);

                    // deleting the default value will in fact unset its value, so we don't want explorer to remove the item visually
                    if (string.IsNullOrEmpty(keyName))
                    {
                        const int COPYENGINE_E_USER_CANCELLED = unchecked ((int)0x80270000);
                        e.HResult = COPYENGINE_E_USER_CANCELLED;
                        e.Item.NotifyUpdate();
                    }
                }
            }
            e.HResult = ShellUtilities.S_OK;
        }
        private async void OnRename(ShellOperationEventArgs e)
        {
            if (e.Item.IsFolder)
            {
                // rename a key
                using (var key = OpenKey(true))
                {
                    if (key != null)
                    {
                        var path = System.IO.Path.Combine(Path ?? string.Empty, e.Item.DisplayName);
                        RegRenameKey(key.Handle, path, e.NewName);
                        e.NewId = new StringKeyShellItemId(e.NewName);
                        e.Item.NotifyRename(e.NewId);
                        e.HResult = ShellUtilities.S_OK;
                    }
                }
                return;
            }

            // rename a value (delete + set)
            using (var key = OpenKey(true))
            {
                if (key != null)
                {
                    if (key.GetValueNames().Contains(e.NewName, StringComparer.OrdinalIgnoreCase))
                    {
                        await WindowsUtilities.DoModelessAsync(() =>
                        {
                            MessageBox.Show(new Win32Window(e.HwndOwner), "The Registry Folder cannot rename '" + e.Item.DisplayName + "'. The specified value name already exists. Type another name and try again.", "Registry Folder", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        });
                    }
                    else
                    {
                        var value = key.GetValue(e.Item.DisplayName);
                        if (value == null)
                        {
                            await WindowsUtilities.DoModelessAsync(() =>
                            {
                                MessageBox.Show(new Win32Window(e.HwndOwner), "The Registry Folder cannot rename '" + e.Item.DisplayName + "'. The specified value name does not exists. Refresh the view and try again.", "Registry Folder", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            });
                        }
                        else
                        {
                            key.SetValue(e.NewName, value);
                            key.DeleteValue(e.Item.DisplayName, false);
                            e.NewId   = new StringKeyShellItemId(e.NewName);
                            e.HResult = ShellUtilities.S_OK;
                            e.Item.Parent?.NotifyUpdate();
                        }
                    }
                }
            }
        }
        protected override void OnOperate(ShellOperationEventArgs e)
        {
            switch (e.Operation)
            {
            case ShellOperation.SetNameOf:
            case ShellOperation.RenameItem:
                OnRename(e);
                break;

            case ShellOperation.RemoveItem:
                OnRemove(e);
                break;
            }
        }
 protected override void OnOperate(ShellOperationEventArgs e)
 {
     Console.WriteLine("OnOperate " + e.Operation);
 }
Example #5
0
        protected override void OnOperate(ShellOperationEventArgs e)
        {
            // some advanced errors number can be found in %ProgramFiles(x86)%\Windows Kits\10\Include\<SDK Version>\um\sherrors.h (for example with SDK Version = 10.0.19041.0)

            var item = (e.Item as IObjectWithApiItem)?.ApiItem;

            switch (e.Operation)
            {
            case ShellOperation.RecycleItem:
                // our recycle bin is only local (a server side recycle bin may be better, but not implemented here)
                if (e.Item is IObjectWithApiItem si && e.Item.FileSystemPath != null)
                {
                    // we copy the file in an accessible folder so the user will be able to get to it when pulling out from recycle bin
                    var recycledPath = si.ApiItem.Recycle();
                    using (var fo = new FileOperation())
                    {
                        fo.SetOperationFlags(FOF.FOFX_RECYCLEONDELETE);
                        fo.DeleteItem(recycledPath);
                        fo.PerformOperations();
                    }

                    if (item.DeleteAsync(e.Item.FileSystemPath, new DeleteOptions {
                        Recursive = true
                    }).Result)
                    {
                        // tell the Shell not to process children (in case of a folder), as the server did it (or failed)
                        const int COPYENGINE_S_DONT_PROCESS_CHILDREN = 0x00270008;
                        e.HResult = COPYENGINE_S_DONT_PROCESS_CHILDREN;
                        NotifyUpdate();
                    }
                    else
                    {
                        // we can only reuse well-known error, for example
                        e.HResult = ShellUtilities.ERROR_RETRY;
                    }
                }
                break;

            case ShellOperation.RemoveItem:
                if (item.DeleteAsync(e.Item.FileSystemPath, new DeleteOptions {
                    Recursive = true
                }).Result)
                {
                    // tell the Shell not to process children (in case of a folder), as the server did it (or failed)
                    const int COPYENGINE_S_DONT_PROCESS_CHILDREN = 0x00270008;
                    e.HResult = COPYENGINE_S_DONT_PROCESS_CHILDREN;
                    NotifyUpdate();
                }
                else
                {
                    // we can only reuse well-known error, for example
                    e.HResult = ShellUtilities.ERROR_RETRY;
                }
                break;

            case ShellOperation.RenameItem:
            case ShellOperation.SetNameOf:
                var result = item.RenameAsync(e.NewName, e.Item.FileSystemPath).Result;
                if (result != null)
                {
                    e.HResult = ShellUtilities.S_OK;
                    NotifyUpdate();
                }
                else
                {
                    // we can only reuse well-known error, for example
                    e.HResult = ShellUtilities.ERROR_RETRY;
                }
                break;
            }
            base.OnOperate(e);
        }