使用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