使用explorer浏览文件

使用explorer浏览文件对象

使用explorer浏览,有两种方式:
1.使用explorer命令行
参数                         结果
/n                          为默认选择内容打开一个新的单窗格窗口。
                            默认选择内容通常是安装 Windows 的驱动器的根目录。
/e                         使用默认视图启动 Windows 资源管理器。
/e, <object>                 使用默认视图启动 Windows 资源管理器并把焦点定位在指定文件夹上。
/root, <object>         打开指定对象的一个窗口视图。
/select, <object>        打开一个窗口视图,指定的文件夹、文件或程序被选中。

例子
Explorer.exe /root,C:/Program Files
但是,使用explorer命令行,会创建一个新的explorer.exe的进程

2.使用SHOpenFolderAndSelectItems函数,这样系统不会创建一个新的explorer.exe进程。
下面的代码由c#实现,并产生为com
//IShellFolder.cs文件
using System;
using System.Text;
using System.Runtime.InteropServices;

namespace ComType {
    #region IShellFolder
    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("000214E6-0000-0000-C000-000000000046")]
    public interface IShellFolder {
        void ParseDisplayName(
            IntPtr hwnd,
            IntPtr pbc,
            [MarshalAs(UnmanagedType.LPWStr)] string pszDisplayName,
            out uint pchEaten,
            out IntPtr ppidl,
            ref uint pdwAttributes);

        [PreserveSig]
        int EnumObjects(IntPtr hWnd,int flags,out IntPtr enumIDList);

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

        void BindToStorage(
            IntPtr pidl,
            IntPtr pbc,
            [In()] ref Guid riid,
            [MarshalAs(UnmanagedType.Interface)] out object ppv);

        [PreserveSig()]
        uint CompareIDs(
            int lParam,
            IntPtr pidl1,
            IntPtr pidl2);

        void CreateViewObject(
            IntPtr hwndOwner,
            [In()] ref Guid riid,
            [MarshalAs(UnmanagedType.Interface)] out object ppv);

        void GetAttributesOf(
            uint cidl,
            [In(),MarshalAs(UnmanagedType.LPArray)] IntPtr[] apidl,
           ref int rgfInOut);

        //[PreserveSig]
        //Int32 GetUIObjectOf(
        //    IntPtr hwndOwner,
        //    uint cidl,
        //    [MarshalAs(UnmanagedType.LPArray)]
        //    IntPtr[] apidl,
        //    Guid riid,
        //    IntPtr rgfReserved,
        //    out IntPtr ppv);
        IntPtr GetUIObjectOf(
            IntPtr hwndOwner,
            uint cidl,
            [MarshalAs(UnmanagedType.LPArray)] IntPtr[] apidl,
            [In()] ref Guid riid,
            out IntPtr rgfReserved);

        void GetDisplayNameOf(
            IntPtr pidl,
            int uFlags,
            IntPtr lpName);

        IntPtr SetNameOf(
            IntPtr hwnd,
            IntPtr pidl,
            [MarshalAs(UnmanagedType.LPWStr)] string pszName,
           int uFlags);
    }
    #endregion IShellFolder
}
------------------------------------------------------------------------
//browse.cs文件
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Diagnostics;

namespace Feng {
  namespace ComInterop {

        /// <summary>
        /// 在explorer浏览器中选中子项
        /// </summary>
        [Guid("e2b8eeca-840a-4454-b4c3-e491d532eb6e")]
        public interface IExplorerSelectItems {
            /// <summary>
            /// 在explorer中打开指定的目录,如果指定的是文件而非目录
            /// </summary>
            /// <param name="folder">目录的路径,如果为null,函数返回S_FALSE</param>
            /// <returns>如果函数成功返回S_OK,否则其他值</returns>
            [DispId(1)]
            uint BrowseItem(string folder);

            /// <summary>
            /// 在explorer中选定指定的子项,可以是子目录或者是子文件
            /// </summary>
            /// <param name="folder">想要在explorer选中子项的指定父目录路径</param>
            /// <param name="items">包含在folder下的子文件和子目录</param>
            /// <returns>成功返回S_OK,否则为其他值</returns>
            [DispId(2)]
            uint SelectItems(string folder,string[] items/* 可以是多个在folder下的文件 */);


        };
        /// <summary>
        /// 对IExplorerSelectItems接口的实现
        /// </summary>
        [Guid("10b3ee95-0a6a-4c51-9aed-16a32414d0a4"),
        ClassInterface(ClassInterfaceType.None)]
        public class ExplorerSelectItems:IExplorerSelectItems {

 

            #region IExplorerSelectItems 成员
            /// <summary>
            /// 在explorer中打开指定的目录,如果指定的是文件而非目录。
            /// 如果是特殊路径,使用System.Environment.GetFolderPath
            /// </summary>
            /// <param name="folder">目录的路径,如果为null,函数返回S_FALSE</param>
            /// <returns>如果函数成功返回S_OK,否则其他值</returns>
            public uint BrowseItem(string folder) {

 

                try {
                    IntPtr pdtf;
                    uint rv=SHGetDesktopFolder(out pdtf);
                    if(rv<0) return rv;

                    if(System.IO.Directory.Exists(folder)==false)

                        return S_FALSE;//S_FALSE

                    ComType.IShellFolder dtf=(ComType.IShellFolder)
                        Marshal.GetObjectForIUnknown(
                        pdtf);
                    uint pchEaten=0;
                    IntPtr pfpidl;
                    uint dwAttributes=1;
                    dtf.ParseDisplayName(
                        IntPtr.Zero,
                        IntPtr.Zero,
                        folder,
                        out pchEaten,
                        out pfpidl,
                        ref dwAttributes
                    );//pfpidl
                    IntPtr pfilepdil=IntPtr.Zero;

                    return SHOpenFolderAndSelectItems(
                        pfpidl,1,ref pfilepdil,0);
                } catch {
                    return S_FALSE;
                }


            }
            /// <summary>
            /// 在explorer中选定指定的子项,可以是子目录或者是子文件
            /// </summary>
            /// <param name="folder">想要在explorer选中子项的指定父目录路径</param>
            /// <param name="items">包含在folder下的子文件和子目录</param>
            /// <returns>成功返回S_OK,否则为其他值</returns>
            public uint SelectItems(string folder,string[] items /*如果items为null,则选中folder,而不是浏览   */) {
                try {
                    if(folder==null
                        ) return 0x00000001;//S_FALSE

                    uint pchEaten=0;
                    IntPtr pfpidl;
                    uint dwAttributes=1;

                    //如果items不属于folder的子文件/目录,将忽略
                    /*1*/
                    if(items==null/* 必须完全限定路径  */) {
                        IntPtr pdtf;
                        uint rv=SHGetDesktopFolder(out pdtf);
                        if(rv<0) return rv;

                        if(System.IO.Directory.Exists(folder)==false)
                            return 0x00000001;//S_FALSE

                        ComType.IShellFolder dtf=(ComType.IShellFolder)
                            Marshal.GetObjectForIUnknown(
                            pdtf);

                        dtf.ParseDisplayName(
                            IntPtr.Zero,
                            IntPtr.Zero,
                            folder,
                            out pchEaten,
                            out pfpidl,
                            ref dwAttributes
                        );//pfpidl

                        IntPtr temp=IntPtr.Zero;

                        return SHOpenFolderAndSelectItems(
                         pfpidl,0,ref temp,0);

                    }
                    /*2检索是否为同folder目录下的,非folder目录下的项,将被忽略*/
                    List<string> item_str=new List<string>();

                    for(int i=0;i<items.Length;i++) {
                        FileInfo fif=new FileInfo(items[i]);
                        if(fif.Exists==false) {
                            if(!Directory.Exists(items[i])) continue;
                        }
                        if(fif.DirectoryName==folder)
                            item_str.Add(items[i]);

                    }
                    int index=0;
                    if((index=item_str.Count)==0) return S_FALSE;

                    IntPtr ppdesktop;

                    SHGetDesktopFolder(out ppdesktop);
                    ComType.IShellFolder pdesktop=(ComType.IShellFolder)
                        Marshal.GetObjectForIUnknown(ppdesktop);

                    if(pdesktop==null) return S_FALSE;

                    IntPtr ppidl=IntPtr.Zero;
                    pdesktop.ParseDisplayName(IntPtr.Zero,IntPtr.Zero,
                        folder,out pchEaten,out ppidl,ref dwAttributes);


                    List<IntPtr> Listpidl=new List<IntPtr>();


                    for(int i=0;i<index;i++) {
                        pdesktop.ParseDisplayName(IntPtr.Zero,IntPtr.Zero,
                            item_str[i],out pchEaten,out pfpidl,ref dwAttributes);
                        if(pfpidl!=IntPtr.Zero)
                            Listpidl.Add(pfpidl);

                    }

                    return SHOpenFolderAndSelectItems(
                            ppidl,
                            Listpidl.Count,
                            Listpidl.ToArray(),
                            0
                             );

                } catch {

                    return S_FALSE;
                }

            }

            #endregion
            /// <summary>
            /// 默认构造函数,实例化一个ExplorerSelectItems对象
            /// </summary>
            public ExplorerSelectItems() { }

            #region def


            [DllImport("shell32")]
            static extern uint SHOpenFolderAndSelectItems
                (IntPtr pidlFolder,int cid1,ref IntPtr apidl,int dwFlags);


            [DllImport("shell32")]
            static extern uint SHOpenFolderAndSelectItems
                (IntPtr pidlFolder,int cid1,IntPtr[] apidl,int dwFlags);

            [DllImport("shell32")]
            static extern uint SHGetDesktopFolder(out IntPtr ppshf);

            const uint S_FALSE=0x00000001;

            #endregion def
        };


    }
}
上面的两个文件生成dll,regasm为com注册,gacutil注册全局缓存

然后在vbs中的调用示例
Set obj= CreateObject("Feng.ComInterop.ExplorerSelectItems")

obj.BrowseItem("c:/windows/system32")

Set obj=Nothing

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值