如何在Linux桌面环境中获取文件的图标、MIME类型和关联应用程序?

29

在Linux桌面上使用C++,获取任意文件/文件路径的图标、文档描述和关联应用程序的最佳方式是什么?我想在KDE和Gnome上使用最“规范”的方式查找图标、mime-type/文件类型描述和关联应用程序,并且我想避免任何“外壳”到命令行和“低级”例程,以及避免自己重新发明轮子(不要解析mime-types文件等)。

编辑和注释:

嘿,我最初问了有关QT文件信息对象的问题,答案“没有明确的答案”似乎是正确的。但这种混乱的情况让我打开了问题,寻找更多信息。

我不再特别关心QT,我只是在寻找通过C++/c函数调用在KDE和Gnome上找到mime类型的最canonical方法(尤其是Gnome,因为那里最让我感到困惑)。我想能够显示与Gnome中Nautilus匹配的图标和描述以及与KDE的Konquerer/whatever匹配的文件,在适当的应用程序中打开这些文件等。

我认为分别获得KDE和Gnome的信息是可以的。最大的问题是,获取Linux桌面所有这些信息的最常见/最佳/最canonical方法是什么?Gnome文档特别晦涩。gnome-vfs具有mime例程,但已被弃用,我找不到GIO/GFS的mime例程,gnome-vsf的替代品。模糊地暗示应使用open desktop应用程序,但哪个应用程序要使用并不清楚。那么libmagic和xdg又在哪里呢?

欢迎指向总结这些问题的文章。再次强调,我知道三行答案是“没有这样的东西”,但我正在寻找答案。


顺便说一下,如果没有更详细的答案,我会让答案奖励过期而不授予任何人... - Joe Soul-bringer
9个回答

16

以下是使用GLib/GIO获取所需信息的示例。

#include <gio/gio.h>
#include <stdio.h>

int
main (int argc, char **argv)
{
    g_thread_init (NULL);
    g_type_init ();

    if (argc < 2)
        return -1;

    GError *error;
    GFile *file = g_file_new_for_path (argv[1]);
    GFileInfo *file_info = g_file_query_info (file,
                                              "standard::*",
                                              0,
                                              NULL,
                                              &error);

    const char *content_type = g_file_info_get_content_type (file_info);
    char *desc = g_content_type_get_description (content_type);
    GAppInfo *app_info = g_app_info_get_default_for_type (
                                  content_type,
                                  FALSE);

    /* you'd have to use g_loadable_icon_load to get the actual icon */
    GIcon *icon = g_file_info_get_icon (file_info);

    printf ("File: %s\nDescription: %s\nDefault Application: %s\n",
            argv[1],
            desc,
            g_app_info_get_executable (app_info));

    return 0;
}

看起来或多或少就是我要找的。有没有关于这些函数的链接文档? - Joe Soul-bringer
http://library.gnome.org/devel/gio/stable/ 是 GIO 文档的主页,根据名称,函数所在的部分应该很明显。 - Travis Watkins
看起来不错:GIO的目标是“提供一个API,使开发人员更喜欢它而不是原始的POSIX调用” - 如果开发人员能够找到这个页面的话!旧的gnomeVFS页面没有链接,也没有使用关键词“Mime”或“文件关联”,在相当长的谷歌搜索中也没有出现 - 现在我知道了!谢谢。 - Joe Soul-bringer
那样做只会返回Nautilus/Gnome的默认应用程序来打开这种类型的文件,对吗? - Albert
不,Nautilus 使用标准的跨桌面方法来确定文件的默认应用程序。即使您在 Nautilus 中覆盖了默认设置,KDE 应用程序也应该尊重它(尚未测试)。 - Travis Watkins
你如何清理所有已分配的内存? - Alex Henrie

4
你可以使用来自xdg的可用工具进行操作,特别是xdg-mime query
要查找例如文件index.html的文件类型,你可以:
$ xdg-mime query filetype index.html

这将返回文件的MIME类型。要查询与该MIME类型相关联的应用程序,请使用以下内容。
$ xdg-mime query default text/html

这里返回的是epiphany.desktop,即$APPNAME.desktop,所以很容易从中获取应用程序的名称。如果你只想在默认应用程序中打开文件,当然可以直接运行。
$ xdg-open index.html

这将启动 Epiphany。

xdg-utils 中似乎没有可用于图标资源的查询函数,但您可以使用 pyxdg 编写一个小型 Python 脚本,它还提供了大量其他功能。

对于 C 绑定,您可能需要查看链接到 xdg 页面的 Portland 代码。

编辑:

关于 libmagic 和相关内容,您需要根据自己的喜好进行决策:虽然 libmagic 在文件类型覆盖范围上似乎更完整(和准确),但它完全不关心默认应用程序或图标。它也不提供安装额外 MIME 类型的工具。


  1. 如何在C++中调用xdg?
  2. 你能详细说明一下xdg/libmagic之间的区别吗?
- Joe Soul-bringer
  1. xdg-utils只是shell脚本,因此您必须使用类似popen()的东西。如果您可以使用Python,请编写专用的pyxdg(或在C++中重新实现专用部分)。
  2. 据我所知,xdg-utils只是前端,用于处理KDE或GNOME扩展-> mimetype数据库,仅在这些失败时回退到libmagic / file以识别mimetype。Libmagic是一个包含二进制文件头的数据库,因此它可以更准确地识别。
使用xdg的最大优点是,您可以将某些功能的责任委托给代码之外,而不是从头开始重写所有内容。
- Benjamin Bannier

3
在Qt >= 4.6中,X11系统有一个新的函数。
QIcon QIcon::fromTheme ( const QString & name, const QIcon & fallback = QIcon() ) [static]

您可以使用此函数。 这里有文档 / (Qt 5)

1

我刚刚发现了KFileItem。这个类在KDE中为您提供了有关图标、MIME类型和相关事项的一切。我相信在GNOME中也有相应的类,但这个类可以像QT应用程序一样访问。


1

QFileIconProvider和QFileInfo都不会使用操作系统mime数据库。要访问与不同mime类型相关联的图标,您将需要使用底层桌面环境的函数。在Qt中,目前还没有官方的方法。

请考虑您可以在Gnome、KDE和Windows中拥有不同的图标。因此,例如,在KDE中,您将使用KMimeType


0

上面的漂亮示例(使用GLib / Gio)的复制/粘贴现在已根据文档添加了适当的分配内存释放。我尝试编辑现有答案,但它一直显示编辑队列已满:(

#include <gio/gio.h>
#include <stdio.h>

int
main (int argc, char **argv)
{
    g_thread_init (NULL);
    g_type_init ();

    if (argc < 2)
        return -1;

    g_autoptr(GError) error;
    GFile* file = g_file_new_for_path (argv[1]);
    GFileInfo* file_info = g_file_query_info (file,
                                              "standard::*",
                                              G_FILE_QUERY_INFO_NONE,
                                              NULL,
                                              &error);

    const char* content_type = g_file_info_get_content_type (file_info);
    g_autofree gchar* desc = g_content_type_get_description (content_type);
    GAppInfo* app_info = g_app_info_get_default_for_type (
                                  content_type,
                                  FALSE);

    /* you'd have to use g_loadable_icon_load to get the actual icon */
    GIcon* icon = g_file_info_get_icon (file_info);

    printf ("File: %s\nDescription: %s\nDefault Application: %s\n",
            argv[1],
            desc,
            g_app_info_get_executable (app_info));

    g_object_unref(file_info);
    g_object_unref(file);
    return 0;
}

0

虽然迟了大约8年,但仍然有用。

要获取与KDE相关的应用程序,可以按照Joe建议的方式(使用KFileItem)进行操作。 但是,这需要包含许多库。下面的代码需要较少的库。

#include <QCoreApplication>
#include <QMimeDatabase>
#include <QDebug>

#include <KMimeTypeTrader>

int main(int argc, char *argv[])
{
  QCoreApplication a(argc, argv);

  if (argc < 2)
  {
    qDebug() << "missing argument <filename>";
    return 1;
  }
  QMimeDatabase mimeDb;
  QMimeType     mimeType = mimeDb.mimeTypeForFile(QString::fromLocal8Bit(argv[1]));

  KService::List services = KMimeTypeTrader::self()->query(
      mimeType.name(),QStringLiteral("Application"));

  foreach(const QExplicitlySharedDataPointer<KService>& svc, services)
  {
    qDebug() << "service: " << svc->name();
    qDebug() << "exec: " << svc->exec();
  }
}

编译代码时,请将QT += KService KCoreAddons添加到您的qmake .pro文件中。

KMimeTypeTrader和KService文档链接:


0

也许可以看一下这段代码: http://ftp.devil-linux.org/pub/devel/sources/1.2/file-4.23.tar.gz

这是大多数Linux/Unix发行版中的标准文件工具。您将获得MIME类型和其他一些信息。

我认为Gnome和KDE都有自己的方法来确定这一点,并设置图标和标准应用程序。

无论如何,那个文件工具可能是获取MIME类型和文档描述的最佳方式。在某些情况下,甚至可以获取有关内容的一些详细信息。

这将为您获取MIME类型。这是您需要知道如何打开文件的必要信息。这些是分开的步骤。文件不会告诉您有关图标或打开文件的应用程序。


可以再提供一些解释吗?我已经浏览了很多代码了。 - Joe Soul-bringer
当我下载归档文件时,它是无效的。 - Joe Soul-bringer
你到底想知道什么?难道你不知道 'file' 命令吗?只需打开终端,输入 "file $somefile"。这个工具非常擅长自动检测文件类型。而且它是相当标准的。我更新了链接,似乎已经失效了。 - Albert
我认为我的问题详细说明了我想要的内容。 - Joe Soul-bringer
文件可能是获取MIME类型和文档描述的最佳方式。当然,这只是其中的一步。请参见我的编辑。 - Albert

0

你可能想使用系统的"/etc/mime.types"文件。同时,维护程序自身的MIME类型文件也是个好主意。这样,你就不会依赖于系统,但同时需要保持其相当全面。对于图标方面不确定。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接