热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C#打开目录并选中文件(夹)的实现

很久之前想把这个写下来的,谁知道用Firefox在博客园上在线编辑快完成时浏览器死掉,郁闷之下没有写了。今天突然想起,随便记录一下吧。本文

  很久之前想把这个写下来的,谁知道用Firefox在博客园上在线编辑快完成时浏览器死掉,郁闷之下没有写了。今天突然想起,随便记录一下吧。

 

  本文想讲的内容,如果你还不是很清楚,可以看看下图:

 


 

  没错,就是想实现像上图中点击“查找目标”按钮一样的功能,即是打开目录并选中文件(夹)。有人可能会问,使用explorer.exe程序加/select参数不是可以做到吗?当然,这是一种办法,不过,也许你更希望使用Windows中的某个API来实现,因为使用explorer.exe程序来实现会有些问题的。那么,Windows中哪个API可以做到呢?答案是shell32.dll中的SHOpenFolderAndSelectItems函数,关于它的详细信息可以查看MSDN,需要注意的是这个API要在Windows XP及以上操作系统才支持。

 

  如果你希望使用VC来实现,那么网上也有很多例子,并且支持Windows XP以下的操作系统,可是我在网上找不到C#实现的例子,或许有我没有找到,所以只好自己动手,丰衣足食了。

 

  首先,C#导入shell32.dll中的SHOpenFolderAndSelectItems函数:

 

        [DllImport("shell32.dll", ExactSpelling = true)]

        public static extern int SHOpenFolderAndSelectItems(

            IntPtr pidlFolder,

            uint cidl,

            [In, MarshalAs(UnmanagedType.LPArray)] IntPtr[] apidl,

            uint dwFlags);

 

  VC中的一些数据类型,我们使用.NET中的IntPtr特定类型来代替行了,因为我们并不关心这些数据类型的数据,知道指针就OK了。SHOpenFolderAndSelectItems的第一个参数pidlFolder指你要查找的目标文件(夹)的PIDL,我们为了获取文件(夹)的PIDL,需要使用shell32.dll中的IShellLink接口。那么我们需要创建IShellLink接口的一个实例,需要使用到ole32.dll中的CoCreateInstance函数。创建的实例保存到指针,如下:

 

        [DllImport("ole32.dll", ExactSpelling = true)]

        public static extern int CoCreateInstance(

            [In] ref Guid rclsid,

            IntPtr pUnkOuter,

            CLSCTX dwClsContext,

            [In] ref Guid riid,

            [Out] out IntPtr ppv);

 

        public enum CLSCTX : uint

        {

            INPROC_SERVER = 0x1

        }

 

        Guid CLSID_ShellLink = new Guid("00021401-0000-0000-C000-000000000046");

        Guid IID_IShellLink = new Guid("000214F9-0000-0000-C000-000000000046");

 

        IntPtr ppsl = IntPtr.Zero;

        int result = CoCreateInstance(

            ref CLSID_ShellLink,

            IntPtr.Zero,

            CLSCTX.INPROC_SERVER,

            ref IID_IShellLink,

            out ppsl);

 

  这样,ppsl变量就保存了IShellLink的一个实例对象,为了使用IShellLink接口中的方法,我们还需要定义IShellLink接口,下面是Unicode版本的IShellLink,名为IShellLinkW:

 

    [ComImport]

    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]

    [Guid("000214F9-0000-0000-C000-000000000046")]

    public interface IShellLinkW

    {

        [PreserveSig]

        int GetPath(StringBuilder pszFile, int cch, [In, Out] ref WIN32_FIND_DATAW pfd, uint fFlags);

 

        [PreserveSig]

        int GetIDList([Out] out IntPtr ppidl);

 

        [PreserveSig]

        int SetIDList([In] ref IntPtr pidl);

 

        [PreserveSig]

        int GetDescription(StringBuilder pszName, int cch);

 

        [PreserveSig]

        int SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);

 

        [PreserveSig]

        int GetWorkingDirectory(StringBuilder pszDir, int cch);

 

        [PreserveSig]

        int SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);

 

        [PreserveSig]

        int GetArguments(StringBuilder pszArgs, int cch);

 

        [PreserveSig]

        int SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);

 

        [PreserveSig]

        int GetHotkey([Out] out ushort pwHotkey);

 

        [PreserveSig]

        int SetHotkey(ushort wHotkey);

 

        [PreserveSig]

        int GetShowCmd([Out] out int piShowCmd);

 

        [PreserveSig]

        int SetShowCmd(int iShowCmd);

 

        [PreserveSig]

        int GetIconLocation(StringBuilder pszIconPath, int cch, [Out] out int piIcon);

 

        [PreserveSig]

        int SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);

 

        [PreserveSig]

        int SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, uint dwReserved);

 

        [PreserveSig]

        int Resolve(IntPtr hwnd, uint fFlags);

 

        [PreserveSig]

        int SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);

    }

 

        [Serializable, StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode), BestFitMapping(false)]

        public struct WIN32_FIND_DATAW

        {

            public uint dwFileAttributes;

            public FILETIME ftCreationTime;

            public FILETIME ftLastAccessTime;

            public FILETIME ftLastWriteTime;

            public uint nFileSizeHigh;

            public uint nFileSizeLow;

            public uint dwReserved0;

            public uint dwReserved1;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]

            public string cFileName;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]

            public string cAlternateFileName;

        }

 

        [Serializable, StructLayout(LayoutKind.Sequential)]

        public struct FILETIME

        {

            public uint dwLowDateTime;

            public uint dwHighDateTime;

        }

 

  上面的定义可以参照VC中的IShellLinkW定义得到。那么,我们就可以把前面创建的IShellLink实例对象转化为IShellLinkW了:

 

IShellLinkW psl = Marshal.GetObjectForIUnknown(ppsl) as IShellLinkW;

 

  然后设置你想获取PIDL的目标路径,以C:\WINDOWS\regedit.exe为例:

 

psl.SetPath(@"C:\WINDOWS\regedit.exe");

 

IntPtr pidl = IntPtr.Zero;

psl.GetIDList(out pidl);

 

  这样,我们就拿到了C:\WINDOWS\regedit.exe的PIDL,保存在IntPtr类型的pidl变量中。接下来就是让SHOpenFolderAndSelectItems方法使用这个PIDL了:

 

SHOpenFolderAndSelectItems(pidl, 0, null, 0);

 

  执行了上面这句代码后,如无意外,Windows就会打开C:\WINDOWS目录,并且选中regedit.exe文件了。最后要做的事情就是清理内存和释放对象:

 

Marshal.FreeCoTaskMem(pidl);

Marshal.Release(ppsl);

 

  主要的功能实现就已经讲完了,如果你要测试,也不难,把上面讲到过的代码合并起来就应该可以执行了。为了方便使用,你可以把它写成一个方法,哪里需要就调用一下即可。

 

  水平有限,文中难免有错或不足,请不吝赐教。

 

  原作:秋忆

  博客:http://qiuyi21.cnblogs.com

 

转:https://www.cnblogs.com/qiuyi21/archive/2009/06/24/1510592.html



推荐阅读
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 解决Sharepoint 2013运行状况分析出现的“一个或多个服务器未响应”问题的方法
    本文介绍了解决Sharepoint 2013运行状况分析中出现的“一个或多个服务器未响应”问题的方法。对于有高要求的客户来说,系统检测问题的存在是不可接受的。文章详细描述了解决该问题的步骤,包括删除服务器、处理分布式缓存留下的记录以及使用代码等方法。同时还提供了相关关键词和错误提示信息,以帮助读者更好地理解和解决该问题。 ... [详细]
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了三种方法来实现在Win7系统中显示桌面的快捷方式,包括使用任务栏快速启动栏、运行命令和自己创建快捷方式的方法。具体操作步骤详细说明,并提供了保存图标的路径,方便以后使用。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • 本文介绍了在MFC下利用C++和MFC的特性动态创建窗口的方法,包括继承现有的MFC类并加以改造、插入工具栏和状态栏对象的声明等。同时还提到了窗口销毁的处理方法。本文详细介绍了实现方法并给出了相关注意事项。 ... [详细]
  • 如何用JNI技术调用Java接口以及提高Java性能的详解
    本文介绍了如何使用JNI技术调用Java接口,并详细解析了如何通过JNI技术提高Java的性能。同时还讨论了JNI调用Java的private方法、Java开发中使用JNI技术的情况以及使用Java的JNI技术调用C++时的运行效率问题。文章还介绍了JNIEnv类型的使用方法,包括创建Java对象、调用Java对象的方法、获取Java对象的属性等操作。 ... [详细]
  • 本文介绍了Java中Currency类的getInstance()方法,该方法用于检索给定货币代码的该货币的实例。文章详细解释了方法的语法、参数、返回值和异常,并提供了一个示例程序来说明该方法的工作原理。 ... [详细]
  • 十大经典排序算法动图演示+Python实现
    本文介绍了十大经典排序算法的原理、演示和Python实现。排序算法分为内部排序和外部排序,常见的内部排序算法有插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。文章还解释了时间复杂度和稳定性的概念,并提供了相关的名词解释。 ... [详细]
  • 全面介绍Windows内存管理机制及C++内存分配实例(四):内存映射文件
    本文旨在全面介绍Windows内存管理机制及C++内存分配实例中的内存映射文件。通过对内存映射文件的使用场合和与虚拟内存的区别进行解析,帮助读者更好地理解操作系统的内存管理机制。同时,本文还提供了相关章节的链接,方便读者深入学习Windows内存管理及C++内存分配实例的其他内容。 ... [详细]
  • 本文介绍了GTK+中的GObject对象系统,该系统是基于GLib和C语言完成的面向对象的框架,提供了灵活、可扩展且易于映射到其他语言的特性。其中最重要的是GType,它是GLib运行时类型认证和管理系统的基础,通过注册和管理基本数据类型、用户定义对象和界面类型来实现对象的继承。文章详细解释了GObject系统中对象的三个部分:唯一的ID标识、类结构和实例结构。 ... [详细]
author-avatar
遗忘的睡骨
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有