简体   繁体   English

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

[英]How do you get the icon, MIME type, and application associated with a file in the Linux Desktop?

Using C++ on the Linux desktop, what is the best way to get the icon, the document description and the application "associated" with an arbitrary file/file path?在 Linux 桌面上使用 C++,获取图标、文档描述和与任意文件/文件路径“关联”的应用程序的最佳方法是什么?

I'd like to use the most "canonical" way to find icons, mime-type/file type descriptions and associated applications on both KDE and gnome and I'd like to avoid any "shelling out" to the command line and "low-level" routines as well as avoiding re-inventing the wheel myself (no parsing the mime-types file and such).我想使用最“规范”的方式在 KDE 和 gnome 上查找图标、mime 类型/文件类型描述和相关应用程序,我想避免对命令行和“低-level”例程以及避免自己重新发明轮子(不解析 mime-types 文件等)。

Edits and Notes:编辑和注释:

Hey, I originally asked this question about the QT file info object and the answer that "there is no clear answer" seems to be correct as far as it goes.嘿,我最初问了这个关于 QT 文件信息对象的问题,“没有明确的答案”的答案就目前而言似乎是正确的。 BUT this is such a screwed-up situation that I am opening the question looking for more information.但这是一个如此糟糕的情况,我正在打开这个问题以寻求更多信息。

I don't care about QT in particular any more, I'm just looking for the most cannonical way to find the mime type via C++/c function calls on both KDE and gnome (especially Gnome, since that's where things confuse me most).我不再特别关心 QT,我只是在寻找通过 KDE 和 gnome 上的 C++/c 函数调用来查找 mime 类型的规范的方法(尤其是 Gnome,因为这是最让我困惑的地方) . I want to be able show icons and descriptions matching Nautilus in Gnome and Konquerer/whatever on KDE as well as opening files appropriately, etc.我希望能够在 Gnome 和 Konquerer/KDE 上的任何内容中显示与 Nautilus 匹配的图标和描述,以及适当地打开文件等。

I suppose it's OK that I get this separately for KDE and Gnome.我想我可以为 KDE 和 Gnome 分别获得它。 The big question is what's the most common/best/cannonical way to get all this information for the Linux desktop?最大的问题是获取 Linux 桌面所有这些信息的最常见/最佳/规范的方式是什么? Gnome documentation is especially opaque. Gnome 文档特别不透明。 gnome-vsf has mime routines but it's deprecated and I can't find a mime routine for GIO/GFS, gnome-vsf's replacement. gnome-vsf 有 mime 例程,但它已被弃用,我找不到 GIO/GFS 的 mime 例程,gnome-vsf 的替代品。 There's a vague implication that one should use the open desktop applications but which one to use is obscure.有一个模糊的含义是应该使用开放的桌面应用程序,但使用哪个应用程序是模糊的。 And where does libmagic and xdg fit in? libmagic 和 xdg 在哪里适合?

Pointers to an essay summarizing the issues gladly accepted.指向一篇总结问题的文章的指针很高兴地被接受。 Again, I know the three line answer is "no such animal" but I'm looking for the long answer.同样,我知道三行答案是“没有这样的动物”,但我正在寻找答案。

Here is an example of using GLib/GIO to get the information you want.以下是使用 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;
}

You can use the tools available from xdg for that, in particular xdg-mime query .为此,您可以使用xdg提供的工具,特别是xdg-mime query

To find out the filetype of eg a file index.html you would要找出例如文件index.html的文件类型,您将

$ xdg-mime query filetype index.html

This will return the mimetype.这将返回 mimetype。 To query what application is associated with that mimetye use eg要查询与该 mimetye 相关联的应用程序,例如

$ xdg-mime query default text/html

This returns epiphany.desktop here, ie $APPNAME.desktop , so it is easy to get the application name from it.这将在此处返回epiphany.desktop ,即$APPNAME.desktop ,因此很容易从中获取应用程序名称。 If you would just want to open the file in the default app you could of course just run如果您只想在默认应用程序中打开文件,您当然可以运行

$ xdg-open index.html

which would fire up epiphany.这会激发顿悟。

Query functions for icon resources do not seem to be available in xdg-utils , but you could write a small python script using pyxdg that offers tons of additional functionality, too.图标资源的查询功能在xdg-utils似乎不可用,但您可以使用pyxdg编写一个小的 python 脚本,也提供大量附加功能。

For C bindings you will probably need to have a look into the portland code linked on the xdg page.对于 C 绑定,您可能需要查看xdg页面上链接的波特兰代码。

EDIT:编辑:

Concerning libmagic and friends, you will need to decide on your preferences: While libmagic seems to be more complete (and accurate) in terms of coverage for filetypes, it does not care at all about default applications or icons.关于libmagic和朋友,您需要决定您的偏好:虽然 libmagic 在文件类型覆盖方面似乎更完整(和准确),但它根本不关心默认应用程序或图标。 It also does not provide you with tools to install extra mimetypes.它也不为您提供安装额外 mimetypes 的工具。

In Qt >= 4.6, there is a new function for X11 systems Qt>=4.6,X11系统新增功能

QIcon QIcon::fromTheme ( const QString & name, const QIcon & fallback = QIcon() ) [static]

You can use this function.您可以使用此功能。 Documentation here / (Qt 5)此处的文档/ (Qt 5)

Neither QFileIconProvider nor QFileInfo will do anything with the OS mime database. QFileIconProvider 和 QFileInfo 都不会对操作系统 mime 数据库做任何事情。 To access icons associated with different mime types, you will have to use functions of the underlying desktop environment.要访问与不同 mime 类型关联的图标,您必须使用底层桌面环境的功能。 In Qt there is (yet) no canonical way.在 Qt 中(还)没有规范的方式。

Consider you can have a different icon in Gnome, in KDE and in Windows.考虑到您可以在 Gnome、KDE ​​和 Windows 中使用不同的图标。 So for instance, in KDE you would use KMimeType .例如,在 KDE 中,您将使用KMimeType

I just found KFileItem .我刚刚找到了KFileItem This class gives you everything you for icons, mime types and related things in KDE.这个类为你提供了 KDE 中图标、mime 类型和相关内容的一切。 I'm sure that there's an equivalent in gnome but this gives access at the same level as a QT application works.我确信 gnome 中有一个等价物,但这提供了与 QT 应用程序工作相同级别的访问权限。

You may want to use the system's "/etc/mime.types" file.您可能希望使用系统的“/etc/mime.types”文件。 It is also a good idea to maintain your program's copy of a MIME type file.维护程序的 MIME 类型文件副本也是一个好主意。 That way, you are not dependent on the system, but at the same time you need to keep it fairly exhaustive.这样,您就不会依赖于系统,但同时您需要使其相当详尽。 Not sure about Icons.不确定图标。

Maybe take a look at this code: http://ftp.devil-linux.org/pub/devel/sources/1.2/file-4.23.tar.gz也许看看这个代码: http : //ftp.devil-linux.org/pub/devel/sources/1.2/file-4.23.tar.gz

This is the standard file util found on most Linux/Unix distributions.这是大多数 Linux/Unix 发行版上的标准文件 util。 You will get the MIME-type and some more information.您将获得 MIME 类型和更多信息。

I think both Gnome and KDE have their own ways to determine this and also to set the icon and the standard application for it.我认为 Gnome 和 KDE 都有自己的方法来确定这一点,并为其设置图标和标准应用程序。

Anyway, that file-tool is probably the best way to get the mime type and the document description.无论如何,该文件工具可能是获取 mime 类型和文档描述的最佳方式。 And in some cases even some details about the content.在某些情况下甚至是关于内容的一些细节。

This will get you the mime-type.这将使您成为哑剧类型。 That is what you need anyway to know how you can open the file.无论如何,这就是您知道如何打开文件所需要的。 These are seperated steps.这些是分开的步骤。 file doesn't say you about the icon nor the application to open the file with. file 不会告诉您有关图标或用于打开文件的应用程序。

About 8 years late, but still useful.晚了大约 8 年,但仍然有用。

To get the associated applications in KDE you can do what Joe suggested (using KFileItem ).要在 KDE 中获取关联的应用程序,您可以执行 Joe 建议的操作(使用KFileItem )。 However, that requires inclusion of a lot of libraries.但是,这需要包含很多库。 The code below requires less.下面的代码需要较少。

#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();
  }
}

To compile the code add QT += KService KCoreAddons to your qmake .pro file.要编译代码,请将QT += KService KCoreAddons添加到您的 qmake .pro文件中。

Links to KMimeTypeTrader & KService documentation: KMimeTypeTrader 和 KService 文档的链接:

Copy/Paste of the nice example above (using GLib/Gio) just added proper release of allocated memory as per documentation.复制/粘贴上面的好例子(使用 GLib/Gio)只是根据文档添加了正确释放分配的内存。 I tried to just edit the existing answer but it kept saying the edit queue was full :(我试图只编辑现有的答案,但它一直说编辑队列已满:(

#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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM