【问题标题】:Getting MetaData information from a file using C#使用 C# 从文件中获取元数据信息
【发布时间】:2014-10-30 06:00:07
【问题描述】:

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

当我尝试运行上述代码时,我收到错误无法将“Shell32.ShellClass”类型的 COM 对象转换为接口类型“Shell32.IShellDispatch6”。此操作失败,因为 IID 为“{286E6F1B-7113-4355-9562-96B7E9D64C54}”的接口的 COM 组件上的 QueryInterface 调用失败,原因是以下错误:不支持此类接口(HRESULT 异常:0x80004002 (E_NOINTERFACE)) .

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

谢谢

【问题讨论】:

  • 此代码的上下文在问题中不可见。但考虑到错误,它在 MTA 中的工作线程上运行的可能性很高。 IShellDispatch6 没有代理,需要一个 STA 线程。

标签: c#-4.0


【解决方案1】:

似乎问题是严格参考构建系统上与目标系统不同的特定版本的 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);

您可以这样创建文件夹对象:

    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(...) 参数是“要为其创建文件夹对象的文件夹。这可以是指定文件夹路径的字符串或 ShellSpecialFolderConstants 值之一。” (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 });
    }

【讨论】:

  • @liferunner_:当我尝试获取 .xlsx 和 .docx 的元数据时。但没有获得这些文件的元数据信息。你能告诉我为什么吗??
  • 仅供参考,对于同样的问题,这里有另一个类似的解决方案可能会有所帮助:stackoverflow.com/questions/12075188/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多