C# 从桌面获取所选文件

C# 从桌面获取所选文件,c#,winapi,C#,Winapi,我正在尝试从桌面获取所选文件的列表。我得到了正确数量的文件,但我得到了像这样奇怪的文件名,例如:㺘ݔ䁐\u0086\u0002。我在用电脑获取信息。这是我的代码: public string GetItemText(int idx) { const int MAX_SIZE = 512; byte[] szBuffer = new byte[MAX_SIZE]; LVITEM lvi = n

我正在尝试从桌面获取所选文件的列表。我得到了正确数量的文件,但我得到了像这样奇怪的文件名,例如:㺘ݔ䁐\u0086\u0002。我在用电脑获取信息。这是我的代码:

        public string GetItemText(int idx)
        {
            const int MAX_SIZE = 512;
            byte[] szBuffer = new byte[MAX_SIZE];

            LVITEM lvi = new LVITEM
            {
                mask = LVIF_TEXT,
                cchTextMax = MAX_SIZE,
                iItem = idx,
                iSubItem = 0,
                pszText = Marshal.AllocHGlobal(MAX_SIZE)
            };

            // Fill LVITEM structure
            IntPtr ptrLvi = Marshal.AllocHGlobal(Marshal.SizeOf(lvi));
            Marshal.StructureToPtr(lvi, ptrLvi, false);
            int readBytes = 0;
            try
            {
                readBytes = SendMessagePtr(ShellListViewHandle, LVM_GETITEM, IntPtr.Zero, ptrLvi);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }

            // Get the text
            string itemText = Marshal.PtrToStringAuto(lvi.pszText);
            return itemText;
        }

你不能用AFAIK来做这件事。您只能从它开始,然后使用本机Shell接口

这里用C/C++解释了这些原理

这里有一个类似的C#控制台应用程序,它可以转储当前在桌面上选择的所有项目名称,您必须根据需要进行调整或扩展:

public class Program
{
    static void Main()
    {
        // we basically follow https://devblogs.microsoft.com/oldnewthing/20130318-00/?p=4933
        dynamic app = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
        var windows = app.Windows;

        const int SWC_DESKTOP = 8;
        const int SWFO_NEEDDISPATCH = 1;
        var hwnd = 0;
        var disp = windows.FindWindowSW(Type.Missing, Type.Missing, SWC_DESKTOP, ref hwnd, SWFO_NEEDDISPATCH);

        var sp = (IServiceProvider)disp;
        var SID_STopLevelBrowser = new Guid("4c96be40-915c-11cf-99d3-00aa004ae837");

        var browser = (IShellBrowser)sp.QueryService(SID_STopLevelBrowser, typeof(IShellBrowser).GUID);
        var view = (IFolderView)browser.QueryActiveShellView();

        view.Items(SVGIO.SVGIO_SELECTION, typeof(IShellItemArray).GUID, out var items);
        if (items is IShellItemArray array)
        {
            for (var i = 0; i < array.GetCount(); i++)
            {
                var item = array.GetItemAt(i);
                Console.WriteLine(item.GetDisplayName(SIGDN.SIGDN_NORMALDISPLAY));
            }
        }
    }

    [Guid("6D5140C1-7436-11CE-8034-00AA006009FA"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IServiceProvider
    {
        [return: MarshalAs(UnmanagedType.IUnknown)]
        object QueryService([MarshalAs(UnmanagedType.LPStruct)] Guid service, [MarshalAs(UnmanagedType.LPStruct)] Guid riid);
    }

    // note: for the following interfaces, not all methods are defined as we don't use them here
    [Guid("000214E2-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IShellBrowser
    {
        void _VtblGap1_12(); // skip 12 methods https://stackoverflow.com/a/47567206/403671

        [return: MarshalAs(UnmanagedType.IUnknown)]
        object QueryActiveShellView();
    }

    [Guid("cde725b0-ccc9-4519-917e-325d72fab4ce"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IFolderView
    {
        void _VtblGap1_5(); // skip 5 methods

        [PreserveSig]
        int Items(SVGIO uFlags, Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object items);
    }

    [Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IShellItem
    {
        [return: MarshalAs(UnmanagedType.IUnknown)]
        object BindToHandler(System.Runtime.InteropServices.ComTypes.IBindCtx pbc, [MarshalAs(UnmanagedType.LPStruct)] Guid bhid, [MarshalAs(UnmanagedType.LPStruct)] Guid riid);

        IShellItem GetParent();

        [return: MarshalAs(UnmanagedType.LPWStr)]
        string GetDisplayName(SIGDN sigdnName);

        // 2 other methods to be defined
    }

    [Guid("b63ea76d-1f85-456f-a19c-48159efa858b"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IShellItemArray
    {
        void _VtblGap1_4(); // skip 4 methods

        int GetCount();
        IShellItem GetItemAt(int dwIndex);
    }

    private enum SIGDN
    {
        SIGDN_NORMALDISPLAY,
        SIGDN_PARENTRELATIVEPARSING,
        SIGDN_DESKTOPABSOLUTEPARSING,
        SIGDN_PARENTRELATIVEEDITING,
        SIGDN_DESKTOPABSOLUTEEDITING,
        SIGDN_FILESYSPATH,
        SIGDN_URL,
        SIGDN_PARENTRELATIVEFORADDRESSBAR,
        SIGDN_PARENTRELATIVE,
        SIGDN_PARENTRELATIVEFORUI
    }

    private enum SVGIO
    {
        SVGIO_BACKGROUND,
        SVGIO_SELECTION,
        SVGIO_ALLVIEW,
        SVGIO_CHECKED,
        SVGIO_TYPE_MASK,
        SVGIO_FLAG_VIEWORDER
    }
}
公共类程序
{
静态void Main()
{
//我们基本上遵循https://devblogs.microsoft.com/oldnewthing/20130318-00/?p=4933
dynamic app=Activator.CreateInstance(Type.GetTypeFromProgID(“Shell.Application”));
var windows=app.windows;
const int SWC_DESKTOP=8;
const int SWFO_NEEDDISPATCH=1;
var-hwnd=0;
var disp=windows.FindWindowSW(Type.Missing,Type.Missing,SWC_DESKTOP,ref hwnd,SWFO_NEEDDISPATCH);
var sp=(IServiceProvider)disp;
var SID_STopLevelBrowser=新Guid(“4c96be40-915c-11cf-99d3-00aa004ae837”);
var browser=(IShellBrowser)sp.QueryService(SID_STopLevelBrowser,typeof(IShellBrowser).GUID);
var view=(IFolderView)browser.QueryActiveShellView();
view.Items(SVGIO.SVGIO_SELECTION,typeof(IShellItemArray).GUID,out var Items);
if(项目为IShellItemArray)
{
对于(var i=0;i
您不能使用AFAIK执行此操作。您只能从它开始,然后使用本机Shell接口

这里用C/C++解释了这些原理

这里有一个类似的C#控制台应用程序,它可以转储当前在桌面上选择的所有项目名称,您必须根据需要进行调整或扩展:

public class Program
{
    static void Main()
    {
        // we basically follow https://devblogs.microsoft.com/oldnewthing/20130318-00/?p=4933
        dynamic app = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
        var windows = app.Windows;

        const int SWC_DESKTOP = 8;
        const int SWFO_NEEDDISPATCH = 1;
        var hwnd = 0;
        var disp = windows.FindWindowSW(Type.Missing, Type.Missing, SWC_DESKTOP, ref hwnd, SWFO_NEEDDISPATCH);

        var sp = (IServiceProvider)disp;
        var SID_STopLevelBrowser = new Guid("4c96be40-915c-11cf-99d3-00aa004ae837");

        var browser = (IShellBrowser)sp.QueryService(SID_STopLevelBrowser, typeof(IShellBrowser).GUID);
        var view = (IFolderView)browser.QueryActiveShellView();

        view.Items(SVGIO.SVGIO_SELECTION, typeof(IShellItemArray).GUID, out var items);
        if (items is IShellItemArray array)
        {
            for (var i = 0; i < array.GetCount(); i++)
            {
                var item = array.GetItemAt(i);
                Console.WriteLine(item.GetDisplayName(SIGDN.SIGDN_NORMALDISPLAY));
            }
        }
    }

    [Guid("6D5140C1-7436-11CE-8034-00AA006009FA"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IServiceProvider
    {
        [return: MarshalAs(UnmanagedType.IUnknown)]
        object QueryService([MarshalAs(UnmanagedType.LPStruct)] Guid service, [MarshalAs(UnmanagedType.LPStruct)] Guid riid);
    }

    // note: for the following interfaces, not all methods are defined as we don't use them here
    [Guid("000214E2-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IShellBrowser
    {
        void _VtblGap1_12(); // skip 12 methods https://stackoverflow.com/a/47567206/403671

        [return: MarshalAs(UnmanagedType.IUnknown)]
        object QueryActiveShellView();
    }

    [Guid("cde725b0-ccc9-4519-917e-325d72fab4ce"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IFolderView
    {
        void _VtblGap1_5(); // skip 5 methods

        [PreserveSig]
        int Items(SVGIO uFlags, Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object items);
    }

    [Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IShellItem
    {
        [return: MarshalAs(UnmanagedType.IUnknown)]
        object BindToHandler(System.Runtime.InteropServices.ComTypes.IBindCtx pbc, [MarshalAs(UnmanagedType.LPStruct)] Guid bhid, [MarshalAs(UnmanagedType.LPStruct)] Guid riid);

        IShellItem GetParent();

        [return: MarshalAs(UnmanagedType.LPWStr)]
        string GetDisplayName(SIGDN sigdnName);

        // 2 other methods to be defined
    }

    [Guid("b63ea76d-1f85-456f-a19c-48159efa858b"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IShellItemArray
    {
        void _VtblGap1_4(); // skip 4 methods

        int GetCount();
        IShellItem GetItemAt(int dwIndex);
    }

    private enum SIGDN
    {
        SIGDN_NORMALDISPLAY,
        SIGDN_PARENTRELATIVEPARSING,
        SIGDN_DESKTOPABSOLUTEPARSING,
        SIGDN_PARENTRELATIVEEDITING,
        SIGDN_DESKTOPABSOLUTEEDITING,
        SIGDN_FILESYSPATH,
        SIGDN_URL,
        SIGDN_PARENTRELATIVEFORADDRESSBAR,
        SIGDN_PARENTRELATIVE,
        SIGDN_PARENTRELATIVEFORUI
    }

    private enum SVGIO
    {
        SVGIO_BACKGROUND,
        SVGIO_SELECTION,
        SVGIO_ALLVIEW,
        SVGIO_CHECKED,
        SVGIO_TYPE_MASK,
        SVGIO_FLAG_VIEWORDER
    }
}
公共类程序
{
静态void Main()
{
//我们基本上遵循https://devblogs.microsoft.com/oldnewthing/20130318-00/?p=4933
dynamic app=Activator.CreateInstance(Type.GetTypeFromProgID(“Shell.Application”));
var windows=app.windows;
const int SWC_DESKTOP=8;
const int SWFO_NEEDDISPATCH=1;
var-hwnd=0;
var disp=windows.FindWindowSW(Type.Missing,Type.Missing,SWC_DESKTOP,ref hwnd,SWFO_NEEDDISPATCH);
var sp=(IServiceProvider)disp;
var SID_STopLevelBrowser=新Guid(“4c96be40-915c-11cf-99d3-00aa004ae837”);
var browser=(IShellBrowser)sp.QueryService(SID_STopLevelBrowser,typeof(IShellBrowser).GUID);
var view=(IFolderView)browser.QueryActiveShellView();
view.Items(SVGIO.SVGIO_SELECTION,typeof(IShellItemArray).GUID,out var Items);
if(项目为IShellItemArray)
{
对于(var i=0;i