(C#)Windows Shell 外壳编程系列2 - 解释,从“桌面”开始展开

简介: (本系列文章由柠檬的(lc_mtt)原创,转载请注明出处,谢谢~)接上一篇:(C#)Windows Shell 外壳编程系列1 - 基础,浏览一个文件夹让我们详细解释一下 Shell 编程中最基本的一些函数、结构体和枚举。

(本系列文章由柠檬的(lc_mtt)原创,转载请注明出处,谢谢~)

接上一篇:(C#)Windows Shell 外壳编程系列1 - 基础,浏览一个文件夹

让我们详细解释一下 Shell 编程中最基本的一些函数、结构体和枚举。

SHGetDesktopFolder 
获取桌面的 IShellFolder 接口

[DllImport("shell32.dll")]
        public static extern Int32 SHGetDesktopFolder(out IntPtr ppshf);


要使用这个函数,必须先定义一个 IntPtr 指针。然后通过指针,使用 GetObjectForIUnknown 返回通过指向 COM 对象的 IShellFolder 接口的指针实例。于是需要编写以下函数:

public static IShellFolder GetDesktopFolder(out IntPtr ppshf)
         {
            SHGetDesktopFolder(out ppshf);
            Object obj = Marshal.GetObjectForIUnknown(ppshf);
            return (IShellFolder)obj;
        }


ParseDisplayName 
获得对象的PIDL,即便对象在目录树中处于当前目录下一层或更多层。例如,对于文件对象来说,它的解析名就是它的路径,我们用文件系统对象的完全路径名来调用桌面的IshellFolder接口的 ParseDisplayName 方法,它会返回这个对象的完全PIDL。定义:

void ParseDisplayName(
            IntPtr hwnd,
            IntPtr pbc,
            [MarshalAs(UnmanagedType.LPWStr)] string pszDisplayName,
            out uint pchEaten,
            out IntPtr ppidl,
            ref uint pdwAttributes);


里面最重要的参数就是 out IntPtr ppidl 了,它返回 pszDisplayName 指定路径对应的 PIDL。然而仅仅是 PIDL 并不能让你做更多的事情。这时候还需要调用 BindToObject 来返回 IShellFolder 接口。

BindToObject 
根据 PIDL 创建和初始化 IShellFolder 对象。定义:

void BindToObject(
            IntPtr pidl,
            IntPtr pbc,
            [In()] ref Guid riid,
            out IShellFolder ppv);


里面有一个 [In()] ref Guid riid 参数,表示接口的接口标识符 (IID)。GUID其实就是一个唯一的标识符。世界上的任何两台计算机都不会生成重复的 GUID 值。GUID 主要用于在拥有多个节点、多台计算机的网络或系统中,分配必须具有唯一性的标识符。我们这里使用 IID_IShellFolder 表示它获取的是一个 IShellFolder 接口。

public static Guid IID_IShellFolder = new Guid("{000214E6-0000-0000-C000-000000000046}");


另外介绍 IEnumIDList 接口。IEnumIDList 接口使资源管理器获得文件夹包含的全部对象的PIDL,PIDL然后可以用来获得这些对象的信息。

因此,我们使用 EnumObjects 函数返回的将是 IEnumIDList 的指针:

int EnumObjects(IntPtr hWnd, SHCONTF flags, out IntPtr enumIDList);


其中 flags 是 SHCONTF 枚举类型,它决定了枚举的内容:

SHCONTF


因此,我们可以通过 flags 的不同来分别列举子文件和子目录。这里会遇到一个问题,怎么获取 PIDL 对象的名称呢。这里编写了2个函数,可以通过 PIDL 或者 IShellFolder 返回对象的名称(详细解释留到下一节):

获取名称


例子二,从“桌面”开始展开

这个例子将使你深入理解之前的内容。它是这样的一个例子,允许你从“桌面”开始,一直展开到最深层的对象。

例2


照例,附图片和源代码:



源代码:/Files/lemony/WinShell2.rar

下一节将讲述 Shell 编程中的 IContextMenu ,也就是上下文菜单,将使你的应用程序列举 Shell 对象的同时,还能在右键操控它们的菜单。

目录
相关文章
|
API C# Windows
C#实现操作Windows窗口句柄:常用窗口句柄相关API、Winform中句柄属性和Process的MainWindowHandle问题【窗口句柄总结之三】
本篇主要介绍一些与窗口句柄相关的一些API,比如设置窗口状态、当前激活的窗口、窗口客户区的大小、鼠标位置、禁用控件等,以及介绍Winform中的句柄属性,便于直接获取控件或窗体句柄,以及不推荐...
5399 0
C#实现操作Windows窗口句柄:常用窗口句柄相关API、Winform中句柄属性和Process的MainWindowHandle问题【窗口句柄总结之三】
|
安全 Linux 开发者
在Linux中,内核模块是什么以及如何加载和卸载它们?
在Linux中,内核模块是什么以及如何加载和卸载它们?
|
云安全 弹性计算 人工智能
阿里acp认证题库试题分享 阿里acp认证考试通过率
云服务云计算是当前十分热门的技术行业,不仅薪资水平高,而且个人职业发展前途也十分开阔。就国内市场而言,阿里云占据了最大份额,再加上阿里集团打造的生态链早已形成规模,因此持有阿里云认证的技术人员在招聘市场非常抢手,为了帮助有志于从事该行业的青年技术人员,今天就分享阿里acp认证题库中的部分试题,同时回答关于认证考试通过率的问题。
3229 0
阿里acp认证题库试题分享 阿里acp认证考试通过率
|
Java
SpringCloud - 如何正确查看 SpringCloud 对应 SpringBoot 的稳定版本?
SpringCloud - 如何正确查看 SpringCloud 对应 SpringBoot 的稳定版本?
695 0
SpringCloud - 如何正确查看 SpringCloud 对应 SpringBoot 的稳定版本?
|
前端开发 JavaScript 架构师
了解微前端,深入前端架构的前世今生
该文章深入探讨了微前端架构的起源、发展及其解决的问题,并详细讲解了微前端在现代Web应用中的实现方式与优势,帮助读者理解微前端的设计理念和技术细节。
|
大数据
.xin 域名信用验证问题集锦
.xin域名是阿里巴巴推出的首个新顶级域,音同“信”,让用户信赖的域名! 欲通过互联网的入口,联合各诚信评价机构(包括阿里巴巴企业诚信体系、芝麻信用等),让每一个愿意展示自身诚信情况的企业或个人都拥有其专属的.xin为后缀的域名,作为互联网上的“诚信标识”,真实展示其诚信指数。
4353 0
|
存储 数据库 数据安全/隐私保护
Windows系统部署AnyTXT Searcher并实现远程搜索本地内网设备中文件
Windows系统部署AnyTXT Searcher并实现远程搜索本地内网设备中文件
|
运维 安全 数据中心
【Terraform实现云服务基础设施既代码(IaC)案例实战-1】:树苗科技公司的自动化转型之旅
背景树苗科技公司业务上云2年有余,随着技术的不断发展。运维团队支持业务变更配置、开资源、删资源等过程加班到深夜一两点已是家常便饭。为了进一步提升工作效率,运维总监张三决定对当前业务交付路径进行统一梳理,借助IaC的理念和Terraform自动化工具逐步实施运维生产自动化,改善组内成员频繁加班的现状。...
1006 57

热门文章

最新文章