(C#)Windows Shell 编程系列1 - 基础,浏览一个文件夹

原文 (C#)Windows Shell 编程系列1 - 基础,浏览一个文件夹

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

Windows Shell 编程,即 Windows 外壳编程。我们所看到的资源管理器以及整个桌面,都是一个 Shell。

关于 Windows 外壳的基本概念,我这里不做详细介绍,不了解的朋友,可以看看 姜伟华 的 Windows外壳名字空间的浏览。
好,现在让我们从基础学起,早日做出一个强大的资源管理器软件。(偶也是初学者,多多指教)

1 - 基础,浏览一个文件夹

我们知道,在win32中是以外壳名字空间的形式来组织文件系统的,在外壳名字空间里的每一个对象(注)都实现了一个IShellFolder的接口,通过这个接口我们可以直接查询或间接得到其他相关的接口。 (注:这里的对象指的是外壳名字空间中的一个节点,对象有可能是一个文件夹,有可能是一个文件,也有可能是一个虚拟文件夹,例如:我的电脑,网上邻居,控制面板等)
在C#中,我们这样定义 IShellFolder 接口:

当然,这个接口还没有列出细节函数。我们要做的仅仅是从最基础开始。
首先我们必须了解,在外壳编程中,要使用 PIDL 路径代替普通路径(如果对 PIDL 不熟悉,请看Windows外壳名字空间的浏览)。
“桌面”是最顶级的文件夹,外壳名字空间中其他各项都可以用从“桌面”开始的 PIDL 加以表示。
如何获取“桌面”的 PIDL 和其 IShellFolder 接口呢,可以通过 API SHGetDesktopFolder:

[DllImport("shell32.dll")]         public static extern Int32 SHGetDesktopFolder(out IntPtr ppshf); /// <summary>         /// 获得桌面 Shell         /// </summary>         public static IShellFolder GetDesktopFolder(out IntPtr ppshf)         {             SHGetDesktopFolder(out ppshf);             Object obj = Marshal.GetObjectForIUnknown(ppshf);             return (IShellFolder)obj;         }
//获得桌面 PIDL             IntPtr desktopPtr;             IShellFolder desktop = API.GetDesktopFolder(out desktopPtr);

好的,我们取得“桌面”的 IShellFolder 接口,就已经成功了一半。现在我需要通过“桌面”,来获取“C:/”这个路径的 PIDL 和 IShellFolder 接口,可以通过 IShellFolder 的 ParseDisplayName 和 BindToObject 函数来实现:

void ParseDisplayName(             IntPtr hwnd,             IntPtr pbc,             [MarshalAs(UnmanagedType.LPWStr)] string pszDisplayName,             out uint pchEaten,             out IntPtr ppidl,             ref uint pdwAttributes); void BindToObject(             IntPtr pidl,             IntPtr pbc,             [In()] ref Guid riid,             out IShellFolder ppv);
//获取 C 盘的 PIDL             string FolderPath = @"C:/";             IntPtr Pidl = IntPtr.Zero;             IShellFolder Root;             uint i, j = 0;             desktop.ParseDisplayName(Handle, IntPtr.Zero, FolderPath, out i, out Pidl, ref j);             desktop.BindToObject(Pidl, IntPtr.Zero, ref Guids.IID_IShellFolder, out Root);

前提是你应该保证路径存在,因为我没有做任何出错控制。这样我们就获得了一个 Root,它表示C盘。通过这个Root,我们可以用 EnumObjects 来循环获取其子项(子文件和子文件夹):

[PreserveSig]         int EnumObjects(IntPtr hWnd, SHCONTF flags, out IntPtr enumIDList);
//循环查找 C 盘下面的文件/文件夹的 PIDL             IEnumIDList fileEnum = null;             IEnumIDList folderEnum = null;             IntPtr fileEnumPtr = IntPtr.Zero;             IntPtr folderEnumPtr = IntPtr.Zero;             IntPtr pidlSub;             int celtFetched;             //获取子文件夹             if (Root.EnumObjects(this.Handle, SHCONTF.FOLDERS | SHCONTF.INCLUDEHIDDEN, out fileEnumPtr) == API.S_OK)             {                 fileEnum = (IEnumIDList)Marshal.GetObjectForIUnknown(fileEnumPtr);                 while (fileEnum.Next(1, out pidlSub, out celtFetched) == 0 && celtFetched == API.S_FALSE)                 {                     //获取显示名称                     string name = API.GetNameByPIDL(pidlSub);                     lvFile.Items.Add(name, 1);                 }             }             //获取子文件             if (Root.EnumObjects(this.Handle, SHCONTF.NONFOLDERS | SHCONTF.INCLUDEHIDDEN, out folderEnumPtr) == API.S_OK)             {                 folderEnum = (IEnumIDList)Marshal.GetObjectForIUnknown(folderEnumPtr);                 while (folderEnum.Next(1, out pidlSub, out celtFetched) == 0 && celtFetched == API.S_FALSE)                 {                     string name = API.GetNameByPIDL(pidlSub);                     lvFile.Items.Add(name, 0);                 }             }

事实上,代码到此结束。然而我发现有太多的结构体和枚举没有介绍(以后会有更多),有兴趣的朋友可以自己查 MSDN ,否则就等待我下一节再介绍了。

最后把图和代码贴上,下一节再详细介绍。

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

posted on 2013-10-30 15:41 NET未来之路 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/3396893.html

(C#)Windows Shell 编程系列1 - 基础,浏览一个文件夹相关推荐

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

    (本系列文章由柠檬的(lc_mtt)原创,转载请注明出处,谢谢-) Windows Shell 编程,即 Windows 外壳编程.我们所看到的资源管理器以及整个桌面,都是一个 Shell. 关于 W ...

  2. (C#)Windows Shell 编程系列3 - 上下文菜单(iContextMenu)(一)右键菜单

    (C#)Windows Shell 编程系列3 - 上下文菜单(iContextMenu)(一)右键菜单 原文 (C#)Windows Shell 编程系列3 - 上下文菜单(iContextMenu ...

  3. #TCGA系列#利用perl提取一个文件夹中的多个文件夹里的注释文本

    我们里用gdc下载TCGA数据时,下载到一个压缩文件包.解压后,会发现里面有多个文件夹,而且最烦人的是:有的文件夹里有annotations.txt,而有的没有. miRNA注释文档有9列 我们利用p ...

  4. windows编程之Windows Shell 编程

    这里仅仅是记录下该资源,推荐到下文列出的连接进行查看 用VC++ 进行Windows Shell 扩展编成 由ccc编译 序言: 看过一些对windows 外壳的扩展程序,在使用上一般都是直接利用wi ...

  5. 《windows核心编程系列》十八谈谈windows钩子

    windows应用程序是基于消息驱动的.各种应用程序对各种消息作出响应从而实现各种功能. windows钩子是windows消息处理机制的一个监视点,通过安装钩子能够达到监视指定窗体某种类型的消息的功 ...

  6. [转]Windows Shell 编程 第十一章 【来源:http://blog.csdn.net/wangqiulin123456/article/details/7987992】...

    第十一章 探索Shell 我们现在将注意力从API转向Windows Shell本身.从这一章往后,我们的目标主要集中在清晰和全面的揭示探测器的工作原理和Shell 命名空间的构成对象上,最后给出客户 ...

  7. Windows Shell编程-第十六章.命名空间扩展

    第十六章 命名空间扩展 探测器使用层次结构表述形成系统的许多对象--文件,文件夹,打印机,网络对象等等.这些对象组合定义了一个命名空间,这是一个封闭的符号或名字集合,其中任何给定的符号或名字都能成功地 ...

  8. shell编程系列25--shell操作数据库实战之备份MySQL数据,并通过FTP将其传输到远端主机...

    shell编程系列25--shell操作数据库实战之备份MySQL数据,并通过FTP将其传输到远端主机备份mysql中的库或者表mysqldump 常用参数详解: -u 用户名 -p 密码 -h 服务 ...

  9. Windows Shell 编程 第六章 【来源:http://blog.csdn.net/wangqiulin123456/article/details/7987951】...

    第六章 快捷方式的最短路径 Windows Shell允许存储任何对象的引用到系统范围内的任何地点.例如,当你从一个文件夹拖拽可执行程序到另一个文件夹时,鼠标自动改变形状给出除拷贝和移动文件之外的第三 ...

最新文章

  1. 深度学习-清晰易懂的马尔科夫链原理介绍
  2. python函数体以冒号起始、并且是缩进格式的_Python基础第三课
  3. 你可以不知道原因,但是,我们不能停止努力。httplook抓取路由配置界面信息...
  4. [Luogu1821][USACO07FEB]银牛派对Silver Cow Party
  5. OpenWrt 之 MT7628 使用GPIO中断
  6. CSS定位总结:position=static/relative/absolute/fixed时的区别、top/bottom/left/right与margin外边距的运用
  7. python3.5+tesseract+adb实现西瓜视频或头脑王者辅助答题
  8. 希尔排序和归并排序(java实现)
  9. 1.Kettle下载与安装
  10. 基于javaweb的在线学习系统
  11. Android动态生成答题卡,手机扫描答题卡改卷的最佳选择——ZipGrade
  12. 只要方向正确,路远不是事
  13. java山海经之轩辕_山海经之情剑轩辕 炼化任务详细攻略
  14. PMP学习考试感悟之——坚持、努力是唯一法宝
  15. 360屏保广告彻底关闭教程
  16. ExtJS 前端 日期数据格式转化
  17. 中集集团全球港航AI高科技独角兽中集飞瞳港口航运新枢纽人工智能技术走向成熟全球前三大船公司及港口码头应用落地港口智能化码头智能化
  18. 智能电动车骑行头盔安全帽方案/APP/PCBA/小程序/开发
  19. 2021 合肥市信息学竞赛小学组
  20. 咖啡粉的粗细如何影响风味?| 啡鸟集

热门文章

  1. python的decimal
  2. 父页面调子iframe页面方法和子iframe调用父页面方法
  3. [buuuctf]ciscn_2019_c_1
  4. 计算机专业师资描述,分析对中职学校计算机专业师资的思考
  5. QQ空间营销策略:寻找用户的痛点
  6. 微信小程序API的介绍
  7. 2021 年苏州大学计算机考研专业课 872 真题 --- 数据结构部分
  8. php井字游戏代码_类Basic卡西欧编程入门(4 矩阵 井字游戏)
  9. 1-10 面向对象之多态
  10. 数独游戏完整java代码_Java实现蓝桥杯数独游戏的示例代码