You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C#获取shell:Desktop这类Shell文件夹的文件和文件夹列表?

问题原因
  • Environment.SpecialFolder.DesktopDirectory指向的是用户本地桌面的物理文件系统目录,仅包含实际存储在该路径下的文件和文件夹。
  • shell:Desktop是Windows Shell提供的虚拟命名空间视图,除了本地桌面内容,还整合了系统级Shell对象(如驱动器、This PC、库),这些对象不属于传统文件系统路径,无法通过DirectoryInfo这类文件系统API访问。
解决方案

要获取shell:Desktop中的所有内容,需要调用Windows Shell API,以下是两种可行实现方式:

方式1:使用Windows API Code Pack

这是最简便的方式,该库封装了Shell相关的.NET接口,无需手动处理原生API:

using Microsoft.WindowsAPICodePack.Shell;

// 获取Shell桌面命名空间实例
ShellObject desktop = ShellObject.FromParsingName("shell:Desktop");

// 遍历所有子项
foreach (ShellObject item in desktop)
{
    Console.WriteLine(item.Name);
    // 若为文件系统项,可获取其实际路径
    if (item is ShellFile file)
        Console.WriteLine($"路径: {file.Path}");
}

需通过NuGet安装WindowsAPICodePack-Shell包。

方式2:手动调用Shell32.dll(无第三方依赖)

如果不想引入外部库,可以直接P/Invoke原生Shell API实现:

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

public class ShellDesktopHelper
{
    [ComImport]
    [Guid("13709620-C279-11CE-A49E-444553540000")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IShellFolder
    {
        void ParseDisplayName(IntPtr hwnd, IntPtr pbc, [MarshalAs(UnmanagedType.LPWStr)] string pszDisplayName, out uint pchEaten, out IntPtr ppidl, ref uint pdwAttributes);
        void EnumObjects(IntPtr hwnd, uint grfFlags, out IEnumIDList ppenumIDList);
    }

    [ComImport]
    [Guid("000214F2-0000-0000-C000-000000000046")]
    private class ShellDesktopFolder { }

    [ComImport]
    [Guid("000214F3-0000-0000-C000-000000000046")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IEnumIDList
    {
        void Next(uint celt, IntPtr rgelt, out uint pceltFetched);
        void Reset();
    }

    [DllImport("shell32.dll", CharSet = CharSet.Unicode)]
    private static extern int SHGetNameFromIDList(IntPtr pidl, uint uFlags, [Out] char[] pszName);

    private const uint SHCONTF_FOLDERS = 0x0001;
    private const uint SHCONTF_NONFOLDERS = 0x0002;
    private const uint SHGNF_NORMAL = 0x0000;

    public static List<string> GetShellDesktopItems()
    {
        var items = new List<string>();
        var desktopFolder = new ShellDesktopFolder() as IShellFolder;
        if (desktopFolder == null) return items;

        desktopFolder.EnumObjects(IntPtr.Zero, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, out var enumIDList);
        enumIDList.Reset();

        IntPtr pidl = IntPtr.Zero;
        uint fetched;
        while (true)
        {
            enumIDList.Next(1, pidl, out fetched);
            if (fetched != 1) break;

            var nameBuffer = new char[260];
            if (SHGetNameFromIDList(pidl, SHGNF_NORMAL, nameBuffer) == 0)
            {
                var name = new string(nameBuffer).TrimEnd('\0');
                items.Add(name);
            }
            Marshal.FreeCoTaskMem(pidl);
        }

        return items;
    }

    // 使用示例
    public static void Main()
    {
        foreach (var item in GetShellDesktopItems())
        {
            Console.WriteLine(item);
        }
    }
}

内容的提问来源于stack exchange,提问作者Indy Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 00:20:39