使用C#从文件中获取MetaData信息

时间:2014-10-30 06:00:08

标签: c#-4.0

我试图使用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))。

还有其他更好的解决方案来读取不同文件格式的元数据吗?请给我一些建议。我会感激你的。

由于

1 个答案:

答案 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 });
    }