如何获取打开的资源管理器窗口的 PIDL?

How to get the PIDL of an open explorer window?(如何获取打开的资源管理器窗口的 PIDL?)
本文介绍了如何获取打开的资源管理器窗口的 PIDL?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道如何获取所有打开的资源管理器窗口,使用 Microsoft Internet Controls COM 库.由此,我能够找到 LocationURL 这些窗口.但是,这仅针对文件系统上的路径设置.似乎当 虚拟对象 显示,如网络打印机或回收站,LocationURL 为空.LocationName 似乎仍设置为开始栏上可见的名称.

I know how to get all open explorer windows, using Microsoft Internet Controls COM library. From this, I am able to find the LocationURL of those windows. However, this is only set for paths on the file system. Seemingly when virtual objects are displayed, like network printers or the recycle bin, LocationURL is empty. LocationName still seems to be set to the name which is visible on the start bar.

当设置了 LocationURL 时,这足以让我知道资源管理器窗口指向的位置,但是我如何才能找出这些特殊文件夹所指向的位置呢?

When LocationURL is set, this is sufficient for my purposes to know where the explorer window is pointing to, but how can I find out what it is pointing to for these special folders?

阅读一下 指向项目标识符列表 (PIDL) 的指针.知道资源管理器窗口中显示的是哪个 PIDL 可以识别这一点.有没有办法找回这个?

Reading up a bit on pointers to an item identifier list (PIDL). Knowing which PIDL is being shown in the explorer window could identify that. Is there any way to retrieve this?

推荐答案

以下是获取当前 Windows 资源管理器窗口的 PIDL 的示例 C# 控制台应用程序代码:

Here is a sample C# Console app code that gets the PIDL of current Windows explorer windows:

class Program
{
    static void Main(string[] args)
    {
        var shellWindows = new ShellWindows();
        foreach (IWebBrowser2 win in shellWindows)
        {
            IServiceProvider sp = win as IServiceProvider;
            object sb;
            sp.QueryService(SID_STopLevelBrowser, typeof(IShellBrowser).GUID, out sb);
            IShellBrowser shellBrowser = (IShellBrowser)sb;
            object sv;
            shellBrowser.QueryActiveShellView(out sv);
            Console.WriteLine(win.LocationURL + " " + win.LocationName);
            IFolderView fv = sv as IFolderView;
            if (fv != null)
            {
                // only folder implementation support this (IE windows do not for example)
                object pf;
                fv.GetFolder(typeof(IPersistFolder2).GUID, out pf);
                IPersistFolder2 persistFolder = (IPersistFolder2)pf;

                // get folder class, for example
                // CLSID_ShellFSFolder for standard explorer folders
                Guid clsid;
                persistFolder.GetClassID(out clsid);
                Console.WriteLine(" clsid:" + clsid);

                // get current folder pidl
                IntPtr pidl;
                persistFolder.GetCurFolder(out pidl);

                // TODO: do something with pidl

                Marshal.FreeCoTaskMem(pidl); // free pidl's allocated memory
            }
        }
    }

    internal static readonly Guid SID_STopLevelBrowser = new Guid(0x4C96BE40, 0x915C, 0x11CF, 0x99, 0xD3, 0x00, 0xAA, 0x00, 0x4A, 0xE8, 0x37);

    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("6D5140C1-7436-11CE-8034-00AA006009FA")]
    internal interface IServiceProvider
    {
        void QueryService([MarshalAs(UnmanagedType.LPStruct)] Guid guidService, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppvObject);
    }

    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("1AC3D9F0-175C-11d1-95BE-00609797EA4F")]
    internal interface IPersistFolder2
    {
        void GetClassID(out Guid pClassID);
        void Initialize(IntPtr pidl);
        void GetCurFolder(out IntPtr pidl);
    }

    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214E2-0000-0000-C000-000000000046")]
    internal interface IShellBrowser
    {
        void _VtblGap0_12(); // skip 12 members
        void QueryActiveShellView([MarshalAs(UnmanagedType.IUnknown)] out object ppshv);
        // the rest is not defined
    }

    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("cde725b0-ccc9-4519-917e-325d72fab4ce")]
    internal interface IFolderView
    {
        void _VtblGap0_2(); // skip 2 members
        void GetFolder([MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);
        // the rest is not defined
    }
}

注意:Shell 接口只是部分定义,因为我们不需要完整的细节.如果您需要其他信息,请随时填写.

Note: Shell interfaces are only partially defined as we don't need the full details. Feel free to complete it if you need other information.

这篇关于如何获取打开的资源管理器窗口的 PIDL?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)