簡體   English   中英

如何使用C#從回收站中刪除多選項目?

[英]How to delete multi-selected items from recyclebin using C#?

在此處輸入圖片說明

如何通過C#或Windows API刪除多項目,我已經搜索了很長時間,沒有解決方案。 我在Shell32.dll中使用FolderItemVerb刪除了文件,但它會同時彈出一個對話框。 如果您知道如何解決此問題,我將不勝感激。 謝謝。

首先,將System.Runtime.InteropService添加到您的項目中。 我們將使用SHEmptyRecycleBin方法,該方法接受3個參數。 之后,使用DllImportShell32.dll導入您的類中。

[DllImport("Shell32.dll")]
static extern int SHEmptyRecycleBin(IntPtr hwnd, string pszRootPath, RecycleFlag dwFlags);

然后為RecycleBin標志(dwFlags)定義一個枚舉。 值以十六進制表示。

enum RecycleFlag : int
{
    SHERB_NOCONFIRMATION = 0x00000001, // No confirmation
    SHERB_NOPROGRESSUI = 0x00000001, // No progress tracking window 
    SHERB_NOSOUND = 0x00000004 // No sound played
}

將以下代碼放在空的回收站按鈕中,該按鈕在Shell32.dll中以以下方式調用系統方法:

SHEmptyRecycleBin(IntPtr.Zero, null, RecycleFlag.SHERB_NOSOUND | RecycleFlag.SHERB_NOCONFIRMATION);

參考: 這里

不是為了膽小的人!

與Windows> = Vista兼容的代碼,沒有XP! XP代碼在結尾

這是我第一次看看Shell32接口...哇!即使最簡單的東西也很復雜:-)但是,COM總是很復雜...現在...有2.5個競爭數據結構/用於在Shell中處理文件的接口... IShellFolder (舊的COM接口,此示例中未使用), IShellItem (新的COM接口,此示例中使用), IDLIST (此處用作PIDLIST_ABSOLUTE ,用於“收集”多個文件,我認為是0.5😀)。 我希望任何地方都不會發生內存泄漏(總是很復雜)。 請注意,.NET將自動釋放COM對象。 我什至還添加了一些編寫的代碼來幫助我進行調試(例如獲得支持動詞列表的代碼)。

現在,這里有COM接口以及一些Shell32.dll PInvoke方法。

[StructLayout(LayoutKind.Sequential)]
public struct PIDLIST_ABSOLUTE
{
    public IntPtr Ptr;
}

[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe")]
public interface IShellItem
{
    void BindToHandler(
        IntPtr pbc,
        [In, MarshalAs(UnmanagedType.LPStruct)] Guid bhid,
        [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid,
        [MarshalAs(UnmanagedType.IUnknown)] out object ppv);

    void GetParent(out IShellItem ppsi);

    void GetDisplayName(int sigdnName, out IntPtr ppszName);

    void GetAttributes(uint sfgaoMask, out uint psfgaoAttribs);

    [PreserveSig]
    int Compare(IShellItem psi, uint hint, out int piOrder);
}

[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("70629033-e363-4a28-a567-0db78006e6d7")]
public interface IEnumShellItems
{
    void Next(int celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] IShellItem[] rgelt, out int pceltFetched);

    void Skip(int celt);

    void Reset();

    void Clone(out IEnumShellItems ppenum);
}

[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("b63ea76d-1f85-456f-a19c-48159efa858b")]
public interface IShellItemArray
{
    void BindToHandler(
        IntPtr pbc,
        [In, MarshalAs(UnmanagedType.LPStruct)] Guid bhid,
        [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid,
        [MarshalAs(UnmanagedType.IUnknown)] out object ppvOut);

    void GetPropertyStore(
        uint flags,
        [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid,
        [MarshalAs(UnmanagedType.IUnknown)] out object ppv);

    void GetPropertyDescriptionList(
        IntPtr keyType,
        [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid,
        [MarshalAs(UnmanagedType.IUnknown)] out object ppv);

    void GetAttributes(uint AttribFlags, uint sfgaoMask, out uint psfgaoAttribs);

    void GetCount(out int pdwNumItems);

    void GetItemAt(int dwIndex, out IShellItem ppsi);

    void EnumItems(out IEnumShellItems ppenumShellItems);
}

[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("000214e4-0000-0000-c000-000000000046")]
public interface IContextMenu
{
    [PreserveSig]
    int QueryContextMenu(IntPtr hMenu, uint indexMenu, int idCmdFirst, int idCmdLast, uint uFlags);

    void InvokeCommand([In] ref CMINVOKECOMMANDINFOEX pici);

    [PreserveSig]
    int GetCommandString(UIntPtr idCmd, uint uType, IntPtr pReserved, IntPtr pszName, int cchMax);
}

[StructLayout(LayoutKind.Sequential)]
public struct CMINVOKECOMMANDINFOEX
{
    public int cbSize;
    public uint fMask;
    public IntPtr hwnd;

    // Non-unicode verbs (are there unicode verbs?)
    [MarshalAs(UnmanagedType.LPStr)]
    public string lpVerb;

    [MarshalAs(UnmanagedType.LPStr)]
    public string lpParameters;

    [MarshalAs(UnmanagedType.LPStr)]
    public string lpDirectory;

    public int nShow;
    public uint dwHotKey;
    public IntPtr hIcon;

    [MarshalAs(UnmanagedType.LPStr)]
    public string lpTitle;

    // Use CMIC_MASK_UNICODE
    [MarshalAs(UnmanagedType.LPWStr)]
    public string lpVerbW;

    [MarshalAs(UnmanagedType.LPWStr)]
    public string lpParametersW;

    [MarshalAs(UnmanagedType.LPWStr)]
    public string lpDirectoryW;

    [MarshalAs(UnmanagedType.LPWStr)]
    public string lpTitleW;

    public int ptInvokeX;
    public int ptInvokeY;
}

// Windows >= Vista
public static class ShellItemUtilities
{
    public static readonly Guid FOLDERID_RecycleBinFolder = new Guid("b7534046-3ecb-4c18-be4e-64cd4cb7d6ac");

    public static readonly Guid BHID_EnumItems = new Guid("94f60519-2850-4924-aa5a-d15e84868039");

    public static readonly Guid BHID_SFUIObject = new Guid("3981e225-f559-11d3-8e3a-00c04f6837d5");

    // From Windows 7
    [DllImport("Shell32.dll", ExactSpelling = true, SetLastError = false)]
    public static extern int SHGetKnownFolderItem(
        [In, MarshalAs(UnmanagedType.LPStruct)] Guid rfid,
        uint dwFlags,
        IntPtr hToken,
        [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid,
        out IShellItem ppv);

    // For Windows Vista
    [DllImport("Shell32.dll", ExactSpelling = true, SetLastError = false)]
    public static extern int SHCreateItemFromIDList(PIDLIST_ABSOLUTE pidl, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IShellItem ppv);

    // For Windows Vista
    [DllImport("Shell32.dll", ExactSpelling = true, SetLastError = false)]
    public static extern int SHGetKnownFolderIDList(
        [In, MarshalAs(UnmanagedType.LPStruct)] Guid rfid,
        uint dwFlags,
        IntPtr hToken,
        out PIDLIST_ABSOLUTE ppidl);

    // From Windows Vista
    [DllImport("Shell32.dll", ExactSpelling = true, SetLastError = false)]
    public static extern int SHGetIDListFromObject([MarshalAs(UnmanagedType.Interface)] object punk, out PIDLIST_ABSOLUTE ppidl);

    [DllImport("Shell32.dll", ExactSpelling = true, SetLastError = false)]
    public static extern int SHCreateShellItemArrayFromIDLists(int cidl, [In] PIDLIST_ABSOLUTE[] rgpidl, out IShellItemArray ppsiItemArray);

    public static IEnumerable<IShellItem> Enumerate(this IShellItem si)
    {
        object pesiTemp;
        si.BindToHandler(IntPtr.Zero, BHID_EnumItems, typeof(IEnumShellItems).GUID, out pesiTemp);
        var pesi = (IEnumShellItems)pesiTemp;

        var items = new IShellItem[10];

        while (true)
        {
            int fetched;

            pesi.Next(1, items, out fetched);

            if (fetched == 0)
            {
                break;
            }

            yield return items[0];
        }
    }
}

public static class ContextMenuUtilities
{
    [DllImport("User32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern IntPtr CreateMenu();

    [DllImport("User32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern bool DestroyMenu(IntPtr hMenu);

    [DllImport("User32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern int GetMenuItemCount(IntPtr hMenu);

    [DllImport("User32.dll", ExactSpelling = true, SetLastError = true)]
    public static extern uint GetMenuItemID(IntPtr hMenu, int nPos);

    [DllImport("User32.dll", CharSet = CharSet.Unicode, EntryPoint = "GetMenuStringW", ExactSpelling = true, SetLastError = true)]
    public static extern int GetMenuString(IntPtr hMenu, uint uIDItem, [Out] StringBuilder lpString, int nMaxCount, uint uFlag);

    public static string[] GetVerbs(IContextMenu cm, bool ansi = true)
    {
        IntPtr menu = IntPtr.Zero;

        try
        {
            menu = CreateMenu();

            // It isn't clear why short.MaxValue, but 0x7FFF is very used around the .NET!
            int res = cm.QueryContextMenu(menu, 0, 0, short.MaxValue, 0);

            if (res < 0)
            {
                Marshal.ThrowExceptionForHR(res);
            }

            //var sb = new StringBuilder(128);

            int count = GetMenuItemCount(menu);

            var verbs = new List<string>(count);

            var handle = default(GCHandle);

            try
            {
                var bytes = new byte[ansi ? 128 : 256];

                handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
                IntPtr ptr = handle.AddrOfPinnedObject();

                for (int i = 0; i < count; i++)
                {
                    uint id = GetMenuItemID(menu, i);

                    if (id == uint.MaxValue)
                    {
                        continue;
                    }

                    //GetMenuString(menu, (uint)i, sb, sb.Capacity, 0x00000400 /* MF_BYPOSITION */);
                    //string description = sb.ToString();
                    //sb.Clear();

                    res = cm.GetCommandString((UIntPtr)id, ansi ? (uint)0x00000002 /* GCS_VALIDATEA */ : 0x00000006 /* GCS_VALIDATEW */, IntPtr.Zero, ptr, bytes.Length);

                    if (res < 0)
                    {
                        continue;
                    }

                    if (res == 0)
                    {
                        res = cm.GetCommandString((UIntPtr)id, ansi ? (uint)0x00000000 /* GCS_VERBA */ : 0x00000004 /* GCS_VERBW */, IntPtr.Zero, ptr, bytes.Length);

                        if (res < 0)
                        {
                            Marshal.ThrowExceptionForHR(res);
                        }

                        verbs.Add(ansi ? Marshal.PtrToStringAnsi(ptr) : Marshal.PtrToStringUni(ptr));
                    }
                }
            }
            finally
            {
                if (handle.IsAllocated)
                {
                    handle.Free();
                }
            }

            return verbs.ToArray();
        }
        finally
        {
            if (menu != IntPtr.Zero)
            {
                DestroyMenu(menu);
            }
        }
    }
}

最后是一個使用它的小示例程序...這是一個小的控制台方法,它將列出回收站中存在的所有文件,將其中的10個放入數組中,並在單個操作(動詞)中將其刪除。 SHGetKnownFolderItem來自Windows 7,因此我正在使用Windows Vista中的SHGetKnownFolderIDList + SHCreateItemFromIDList

此處的代碼枚舉了IShellItem包含的IShellItem文件,將其PIDL_ABSOLUTE保存在List<> ,從該List<>創建一個IShellItemArray ,在該IShellItemArray綁定一個IContextMenu ,該IContextMenu執行delete動詞。 顯然,通過將所有PIDL_ABSOLUTE添加/不添加到List<>您可以控制要刪除的文件。

private static void TestShellItem()
{
    IShellItem recyleBin;
    string str;
    IntPtr ptr = IntPtr.Zero;
    int res;

    //// From Windows 7
    //res = ShellItemUtilities.SHGetKnownFolderItem(ShellItemUtilities.FOLDERID_RecycleBinFolder, 0, IntPtr.Zero, typeof(IShellItem).GUID, out recyleBin);

    //if (res < 0)
    //{
    //    Marshal.ThrowExceptionForHR(res);
    //}

    // Windows >= Vista equivalent
    var pidl = default(PIDLIST_ABSOLUTE);

    try
    {
        res = ShellItemUtilities.SHGetKnownFolderIDList(ShellItemUtilities.FOLDERID_RecycleBinFolder, 0, IntPtr.Zero, out pidl);

        if (res < 0)
        {
            Marshal.ThrowExceptionForHR(res);
        }

        res = ShellItemUtilities.SHCreateItemFromIDList(pidl, typeof(IShellItem).GUID, out recyleBin);

        if (res < 0)
        {
            Marshal.ThrowExceptionForHR(res);
        }
    }
    finally
    {
        Marshal.FreeCoTaskMem(pidl.Ptr);
    }

    //// Example of use of GetDisplayName
    //try
    //{
    //    recyleBin.GetDisplayName(2, out ptr);
    //    str = Marshal.PtrToStringUni(ptr);
    //}
    //finally
    //{
    //    if (ptr != IntPtr.Zero)
    //    {
    //        Marshal.FreeCoTaskMem(ptr);
    //        ptr = IntPtr.Zero;
    //    }
    //}

    var pids = new List<PIDLIST_ABSOLUTE>();

    try
    {
        foreach (IShellItem si in recyleBin.Enumerate())
        {
            try
            {
                si.GetDisplayName(0, out ptr);

                str = Marshal.PtrToStringUni(ptr);

                // Some condition to include/exclude...
                if (pids.Count < 10)
                {
                    Console.WriteLine(str);

                    // Remember to free the pidl!
                    res = ShellItemUtilities.SHGetIDListFromObject(si, out pidl);

                    if (res < 0)
                    {
                        Marshal.ThrowExceptionForHR(res);
                    }

                    pids.Add(pidl);
                }
            }
            finally
            {
                if (ptr != IntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(ptr);
                    ptr = IntPtr.Zero;
                }
            }
        }

        var pids2 = pids.ToArray();

        IShellItemArray sia;

        res = ShellItemUtilities.SHCreateShellItemArrayFromIDLists(pids2.Length, pids2, out sia);

        if (res < 0)
        {
            Marshal.ThrowExceptionForHR(res);
        }

        object cmTemp;
        sia.BindToHandler(IntPtr.Zero, ShellItemUtilities.BHID_SFUIObject, typeof(IContextMenu).GUID, out cmTemp);
        var cm = (IContextMenu)cmTemp;

        // To see verbs
        //var verbsAnsi = ContextMenuUtilities.GetVerbs(cm, true);
        //var verbsUnicode = ContextMenuUtilities.GetVerbs(cm, false);

        var cmd = new CMINVOKECOMMANDINFOEX
        {
            cbSize = Marshal.SizeOf(typeof(CMINVOKECOMMANDINFOEX)),
            fMask = 0x00000400 /* CMIC_MASK_FLAG_NO_UI */,
            lpVerb = "delete",
        };

        cm.InvokeCommand(ref cmd);
    }
    finally
    {
        foreach (var pid in pids)
        {
            Marshal.FreeCoTaskMem(pid.Ptr);
        }
    }

    //// Verb executed one by one
    //foreach (var item in recyleBin.Enumerate())
    //{
    //    object cmTemp;
    //    item.BindToHandler(IntPtr.Zero, ShellItemUtilities.BHID_SFUIObject, typeof(IContextMenu).GUID, out cmTemp);
    //    var cm = (IContextMenu)cmTemp;

    ////// To see verbs
    ////    var verbsAnsi = ContextMenuUtilities.GetVerbs(cm, true);
    ////    var verbsUnicode = ContextMenuUtilities.GetVerbs(cm, false);

    //    var cmd = new CMINVOKECOMMANDINFOEX
    //    {
    //        cbSize = Marshal.SizeOf(typeof(CMINVOKECOMMANDINFOEX)),
    //        fMask = 0x00000400 /* CMIC_MASK_FLAG_NO_UI */,
    //        lpVerb = "delete",
    //    };

    //    cm.InvokeCommand(ref cmd);
    //}
}

Windows XP的代碼,使用其他版本的代碼,您需要采取必要的措施

它使用IShellFolder接口。 請注意, IContextMenu處理完全相同。

[StructLayout(LayoutKind.Sequential)]
public struct PIDLIST_RELATIVE
{
    public IntPtr Ptr;
}

[StructLayout(LayoutKind.Sequential)]
public struct LPITEMIDLIST
{
    public IntPtr Ptr;
}

[StructLayout(LayoutKind.Sequential)]
public struct PITEMID_CHILD
{
    public IntPtr Ptr;
}

public enum STRRET_TYPE
{
    WSTR = 0,
    OFFSET = 0x1,
    CSTR = 0x2
};

[StructLayout(LayoutKind.Sequential, Pack = 8, Size = 268)]
public sealed class STRRET : IDisposable
{
    public STRRET_TYPE uType;
    public IntPtr pOleStr;

    [DllImport("Shlwapi.dll", ExactSpelling = true, SetLastError = false)]
    private static extern int StrRetToBSTR(STRRET pstr, PITEMID_CHILD pidl, [MarshalAs(UnmanagedType.BStr)] out string pbstr);

    ~STRRET()
    {
        Dispose(false);
    }

    public override string ToString()
    {
        return ToString(default(PITEMID_CHILD));
    }

    public string ToString(PITEMID_CHILD pidl)
    {
        if (uType == STRRET_TYPE.WSTR)
        {
            if (pOleStr == IntPtr.Zero)
            {
                return null;
            }

            string str = Marshal.PtrToStringUni(pOleStr);
            return str;
        }
        else
        {
            string str;

            int res = StrRetToBSTR(this, pidl, out str);

            if (res < 0)
            {
                Marshal.ThrowExceptionForHR(res);
            }

            return str;
        }
    }


    #region IDisposable Support

    // This code added to correctly implement the disposable pattern.
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    #endregion

    private void Dispose(bool disposing)
    {
        Marshal.FreeCoTaskMem(pOleStr);
        pOleStr = IntPtr.Zero;
    }
}

[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("000214e6-0000-0000-c000-000000000046")]
public interface IShellFolder
{
    void ParseDisplayName(
        IntPtr hwnd,
        IntPtr pbc,
        [MarshalAs(UnmanagedType.LPWStr)] string pszDisplayName,
        out int pchEaten,
        out PIDLIST_RELATIVE ppidl,
        ref uint pdwAttributes);

    void EnumObjects(IntPtr hwnd, uint grfFlags, out IEnumIDList ppenumIDList);

    void BindToObject(
        PIDLIST_RELATIVE pidl,
        IntPtr pbc,
        [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid,
        [MarshalAs(UnmanagedType.IUnknown)] out object ppv);

    void BindToStorage(
        PIDLIST_RELATIVE pidl,
        IntPtr pbc,
        [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid,
        [MarshalAs(UnmanagedType.IUnknown)] out object ppv);

    [PreserveSig]
    int CompareIDs(IntPtr lParam, PIDLIST_RELATIVE pidl1, PIDLIST_RELATIVE pidl2);

    void CreateViewObject(
        IntPtr hwndOwner,
        [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid,
        [MarshalAs(UnmanagedType.IUnknown)] out object ppv);

    void GetAttributesOf(
        int cidl,
        [In, MarshalAs(UnmanagedType.LPArray)] LPITEMIDLIST[] apidl,
        ref uint rgfInOut);

    void GetUIObjectOf(
        IntPtr hwndOwner,
        int cidl,
        [In, MarshalAs(UnmanagedType.LPArray)] PITEMID_CHILD[] apidl,
        [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid,
        IntPtr rgfReserved,
        [MarshalAs(UnmanagedType.IUnknown)] out object ppv);

    void GetDisplayNameOf(
        PITEMID_CHILD pidl,
        uint uFlags,
        STRRET pName);

    void SetNameOf(
        IntPtr hwnd,
        PITEMID_CHILD pidl,
        [MarshalAs(UnmanagedType.LPWStr)] string pszName,
        uint uFlags,
        out PITEMID_CHILD ppidlOut);
}

[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("000214f2-0000-0000-c000-000000000046")]
public interface IEnumIDList
{
    void Next(int celt, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] PITEMID_CHILD[] rgelt, out int pceltFetched);

    void Skip(int celt);

    void Reset();

    void Clone(out IEnumIDList ppenum);
}

// Windows >= XP
public static class ShellFolderUtilities
{
    [DllImport("Shell32.dll", ExactSpelling = true, SetLastError = false)]
    public static extern int SHGetSpecialFolderLocation(IntPtr hwnd, int csidl, out PIDLIST_ABSOLUTE ppidl);

    [DllImport("Shell32.dll", ExactSpelling = true, SetLastError = false)]
    public static extern int SHGetDesktopFolder(out IShellFolder ppshf);

    public static readonly int CSIDL_DESKTOP = 0x0000;

    public static readonly int CSIDL_BITBUCKET = 0x000a;

    // https://blogs.msdn.microsoft.com/oldnewthing/20110830-00/?p=9773
    public static void BindToCsidl(int csidl, Guid riid, out object ppv)
    {
        var pidl = default(PIDLIST_ABSOLUTE);

        try
        {
            int res;

            if (csidl != CSIDL_DESKTOP)
            {
                res = SHGetSpecialFolderLocation(IntPtr.Zero, csidl, out pidl);

                if (res < 0)
                {
                    Marshal.ThrowExceptionForHR(res);
                }
            }

            IShellFolder psfDesktop;
            res = SHGetDesktopFolder(out psfDesktop);

            if (res < 0)
            {
                Marshal.ThrowExceptionForHR(res);
            }

            if (csidl == CSIDL_DESKTOP)
            {
                ppv = psfDesktop;
                return;
            }

            psfDesktop.BindToObject(new PIDLIST_RELATIVE { Ptr = pidl.Ptr }, IntPtr.Zero, riid, out ppv);
        }
        finally
        {
            Marshal.FreeCoTaskMem(pidl.Ptr);
        }
    }

    public static IEnumerable<PITEMID_CHILD> Enumerate(this IShellFolder sf)
    {
        IEnumIDList ppenumIDList;
        sf.EnumObjects(IntPtr.Zero, 0x00020 /* SHCONTF_FOLDERS */ | 0x00040 /* SHCONTF_NONFOLDERS */, out ppenumIDList);

        if (ppenumIDList == null)
        {
            yield break;
        }

        var items = new PITEMID_CHILD[1];

        while (true)
        {
            int fetched;

            ppenumIDList.Next(items.Length, items, out fetched);

            if (fetched == 0)
            {
                break;
            }

            yield return items[0];
        }
    }
}

最后是一個使用它的小示例程序...

private static void TestShellFolder()
{
    object recycleBinTemp;
    ShellFolderUtilities.BindToCsidl(ShellFolderUtilities.CSIDL_BITBUCKET, typeof(IShellFolder).GUID, out recycleBinTemp);
    var recycleBin = (IShellFolder)recycleBinTemp;

    var pids = new List<PITEMID_CHILD>();

    try
    {
        foreach (PITEMID_CHILD pidl in recycleBin.Enumerate())
        {
            // Remember to free the pidl!

            string str;

            using (var ret = new STRRET { uType = STRRET_TYPE.CSTR })
            {

                recycleBin.GetDisplayNameOf(pidl, 0, ret);
                str = ret.ToString(pidl);
            }


            // Some condition to include/exclude...
            if (pids.Count < 10)
            {
                Console.WriteLine(str);
                pids.Add(pidl);
            }
            else
            {
                Marshal.FreeCoTaskMem(pidl.Ptr);
            }
        }

        var pids2 = pids.ToArray();

        object cmTemp;
        recycleBin.GetUIObjectOf(IntPtr.Zero, pids2.Length, pids2, typeof(IContextMenu).GUID, IntPtr.Zero, out cmTemp);
        var cm = (IContextMenu)cmTemp;


        // To see verbs
        //var verbsAnsi = ContextMenuUtilities.GetVerbs(cm, true);
        //var verbsUnicode = ContextMenuUtilities.GetVerbs(cm, false);

        var cmd = new CMINVOKECOMMANDINFOEX
        {
            cbSize = Marshal.SizeOf(typeof(CMINVOKECOMMANDINFOEX)),
            fMask = 0x00000400 /* CMIC_MASK_FLAG_NO_UI */,
            lpVerb = "delete",
        };

        cm.InvokeCommand(ref cmd);
    }
    finally
    {
        foreach (var pid in pids)
        {
            Marshal.FreeCoTaskMem(pid.Ptr);
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM