有两种实用方法可以从C#访问Shell命名空间,将MS WindowsApiCodePack桥连接到IShellFolder
以及相关内容(在NuGet上可用),或者直接引用Shell32(Microsoft Shell控件和自动化)。这两种方法基本相似,尽管第一种方法具有更多功能(我最感兴趣的是支持图像缩略图和更好的文件复制功能)。
枚举此PC 文件夹:
string ThisPC = "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}";
var folder = ShellFolder.FromParsingName(ThisPC) as ShellFolder;
foreach (var child in folder)
或
var shellAppType = Type.GetTypeFromProgID("Shell.Application");
object shell = Activator.CreateInstance(shellAppType);
var ThisPC = (Folder)shellAppType.InvokeMember("NameSpace", BindingFlags.InvokeMethod, null, shell, new object[] { 0x11 });
foreach (FolderItem child in ThisPC.Items())
但两者之间有一个非常重要的区别:第二个枚举设备,如连接手机,而第一个没有。我使用Api Code Pack是开源的并且修改了ShellFolderItems
构造函数(这是ShellFolder
迭代的东西)来尝试
HResult hr = nativeShellFolder.NativeShellFolder.EnumObjects(
IntPtr.Zero,
//ShellNativeMethods.ShellFolderEnumerationOptions.IncludeHidden | ShellNativeMethods.ShellFolderEnumerationOptions.IncludeSuperHidden |
//ShellNativeMethods.ShellFolderEnumerationOptions.Shareable |
ShellNativeMethods.ShellFolderEnumerationOptions.Folders | ShellNativeMethods.ShellFolderEnumerationOptions.NonFolders | ShellNativeMethods.ShellFolderEnumerationOptions.Storage,
out nativeEnumIdList);
最初为文件夹和NonFolders过滤的代码,但这首先排除了手机。所以我添加了存储,隐藏的东西,我能想到的所有组合,但没有任何区别。某些过滤器组合将删除已枚举的项目,但不会将其增加到设备。
我能做些什么才能使第一种方法与第二种方法一样枚举?
更新:使更容易重现,这是整个程序,真的不比上面描述的更多:
using System;
using System.Reflection;
using Microsoft.WindowsAPICodePack.Shell;
using Shell32;
namespace ConsoleApp1 {
class Program {
private static void ShellObjects1() {
string ThisPC = "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}";
var folder = ShellFolder.FromParsingName(ThisPC) as ShellFolder;
foreach (var child in folder)
Console.WriteLine($"{child.Name} = {child.ParsingName}");
}
private static void ShellObjects2() {
var shellAppType = Type.GetTypeFromProgID("Shell.Application");
object shell = Activator.CreateInstance(shellAppType);
var ThisPC = (Folder)shellAppType.InvokeMember("NameSpace", BindingFlags.InvokeMethod, null, shell, new object[] { 0x11 });
foreach (FolderItem child in ThisPC.Items())
Console.WriteLine($"{child.Name} = {child.Path}");
}
static void Main(string[] args) {
Console.WriteLine("WindowsAPICodePack");
ShellObjects1();
Console.WriteLine();
Console.WriteLine("Shell32");
ShellObjects2();
Console.WriteLine();
}
}
}
您应该从COM项中添加对Microsoft Shell的引用,并安装Microsoft.WindowsAPICodePack-Shell NuGet包以进行编译。当我运行这个时,两个列表几乎完全相同。就像在Explorer窗口中一样,首先是文件夹,然后是驱动器。但是在第二个列表中,将会有一个额外的条目:一个设备。就像在Explorer中一样。第一个清单中缺少该项目。
答案 0 :(得分:0)
IDelegateFolder
使得单一界面错过了节拍。
[STAThread]
static void Main(string[] args) {