我试图使用Shell从文件中获取元数据。我正在使用MVC5和Windows 8操作系统。以下是代码。
代码
public JsonResult Ind(string file)
{
List<string> arrHeaders = new List<string>();
string filename = Path.GetFileName(file);
Shell shell = new ShellClass();
Folder rFolder = shell.NameSpace(file);
FolderItem rFiles = rFolder.ParseName(filename);
for (int i = 0; i < short.MaxValue; i++)
{
string value = rFolder.GetDetailsOf(rFiles, i).Trim();
arrHeaders.Add(value);
}
return Json(arrHeaders, JsonRequestBehavior.AllowGet);
}
当我尝试运行上面的代码时,我收到错误无法转换类型为&#39; Shell32.ShellClass&#39;的COM对象接口类型&#39; Shell32.IShellDispatch6&#39;。此操作失败,因为QueryInterface调用COM组件上的接口与IID&#39; {286E6F1B-7113-4355-9562-96B7E9D64C54}&#39;由于以下错误而失败:不支持此类接口(来自HRESULT的异常:0x80004002(E_NOINTERFACE))。
还有其他更好的解决方案来读取不同文件格式的元数据吗?请给我一些建议。我会感激你的。
由于
答案 0 :(得分:8)
似乎问题是严格引用构建系统上的Shell32对象的特定版本,这与目标系统不同。
以下是您在项目文件中的引用(在给定的情况下为C#项目):
<COMReference Include="Shell32">
<Guid>{50A7E9B0-70EF-11D1-B75A-00A0C90564FE}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
</COMReference>
所以在引用你之后你会使用特定版本的Shell(ShellClass)来实现
[Guid("D8F015C0-C278-11CE-A49E-444553540000")]
[TypeLibType(4176)]
public interface IShellDispatch
要在不同平台上防止这种情况,最好使用反射按名称创建所需对象,而不是使用特定版本\库引用特定类型。而不是这段代码:
Shell shell = new ShellClass();
Folder rFolder = shell.NameSpace(file);
您可以这样创建Folder对象:
private static Folder GetShell32NameSpaceFolder(Object folder)
{
var shellAppType = Type.GetTypeFromProgID("Shell.Application");
var shell = Activator.CreateInstance(shellAppType);
return (Folder)shellAppType.InvokeMember("NameSpace",
System.Reflection.BindingFlags.InvokeMethod, null, shell, new [] { folder });
}
另请注意,方法shell.NameSpace(...)参数是&#34;要为其创建Folder对象的文件夹。这可以是一个字符串,它指定文件夹的路径或一个ShellSpecialFolderConstants值。&#34; (MSDN),所以你应该传递不是文件路径,而是传递所需文件的目录路径,例如Path.GetDirectoryName(file)。
所以你的代码应该这样工作:
public JsonResult Ind(string file)
{
List<string> arrHeaders = new List<string>();
string filename = Path.GetFileName(file);
Folder rFolder = GetShell32NameSpaceFolder(Path.GetDirectoryName(file));
FolderItem rFiles = rFolder.ParseName(filename);
for (int i = 0; i < short.MaxValue; i++)
{
string value = rFolder.GetDetailsOf(rFiles, i).Trim();
arrHeaders.Add(value);
}
return Json(arrHeaders, JsonRequestBehavior.AllowGet);
}
private static Folder GetShell32NameSpaceFolder(Object folder)
{
var shellAppType = Type.GetTypeFromProgID("Shell.Application");
var shell = Activator.CreateInstance(shellAppType);
return (Folder)shellAppType.InvokeMember("NameSpace",
System.Reflection.BindingFlags.InvokeMethod, null, shell, new [] { folder });
}