Как получить значок, тип MIME и приложение, связанное с файлом на рабочем столе Linux?
Используя C++ на рабочем столе Linux, как лучше всего получить значок, описание документа и приложение, "связанное" с произвольным путем к файлу / файлу?
Я хотел бы использовать самый "канонический" способ поиска значков, описаний mime-типов / типов файлов и связанных приложений как в KDE, так и в gnome, и я бы хотел избежать "обстрела" командной строки и "низкого уровня" -уровень ", а также избегая повторного изобретения колеса самостоятельно (без разбора файла mime-types и тому подобного).
Редактирует и отмечает:
Привет, я изначально задал этот вопрос об объекте информации файла QT, и ответ, что "нет четкого ответа", кажется, верен, насколько это возможно. НО это такая испорченная ситуация, что я открываю вопрос в поисках дополнительной информации.
В частности, меня больше не волнует QT, я просто ищу наиболее канонический способ найти mime-тип с помощью вызовов функций C++/c как в KDE, так и в gnome (особенно в Gnome, поскольку именно здесь меня больше всего смущает), Я хочу иметь возможность показывать значки и описания, соответствующие Nautilus в Gnome и Konquerer/ что угодно в KDE, а также открывать файлы соответствующим образом и т. Д.
Я полагаю, это нормально, что я получаю это отдельно для KDE и Gnome. Большой вопрос в том, какой самый распространенный / лучший / канонический способ получить всю эту информацию для рабочего стола Linux? Документация гнома особенно непрозрачна. У gnome-vsf есть подпрограммы mime, но она устарела, и я не могу найти подпрограмму mime для GIO/GFS, заменяющей gnome-vsf. Существует смутное предположение, что следует использовать приложения с открытым рабочим столом, но какое использовать неясно. И где вписываются libmagic и xdg?
Указатели на эссе с кратким изложением проблем с радостью приняты. Опять же, я знаю, что ответ из трех строк - "нет такого животного", но я ищу длинный ответ.
9 ответов
Вот пример использования 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;
}
Для этого вы можете использовать инструменты, доступные в xdg, в частности xdg-mime query
,
Чтобы узнать тип файла, например, файл index.html
ты бы
$ xdg-mime query filetype index.html
Это вернет mimetype. Для запроса, какое приложение связано с этим mimetye, используйте, например,
$ xdg-mime query default text/html
Это возвращает epiphany.desktop
здесь, т.е. $APPNAME.desktop
, так что легко получить имя приложения из него. Если вы просто хотите открыть файл в приложении по умолчанию, вы, конечно, можете просто запустить
$ xdg-open index.html
что бы зажечь Богоявление.
Функции запросов к ресурсам значков, по-видимому, недоступны в xdg-utils
, но вы можете написать небольшой скрипт на python, используя pyxdg, который также предлагает множество дополнительных функций.
Для привязки к Си вам, вероятно, нужно взглянуть на код порта, связанный на странице xdg.
РЕДАКТИРОВАТЬ:
Что касается libmagic
и друзья, вам нужно будет определиться с вашими предпочтениями: хотя libmagic выглядит более полным (и точным) с точки зрения охвата типов файлов, он не заботится о приложениях или значках по умолчанию. Он также не предоставляет вам инструментов для установки дополнительных типов MIME.
В Qt >= 4.6 есть новая функция для систем X11
QIcon QIcon::fromTheme ( const QString & name, const QIcon & fallback = QIcon() ) [static]
Вы можете использовать эту функцию. Документация здесь / (Qt 5)
Ни QFileIconProvider, ни QFileInfo ничего не будут делать с базой данных Mime ОС. Чтобы получить доступ к значкам, связанным с различными типами пантомимы, вам придется использовать функции базовой среды рабочего стола. В Qt нет (пока) канонического пути.
Представьте, что у вас может быть другой значок в Gnome, в KDE и в Windows. Так, например, в KDE вы бы использовали KMimeType.
Я только что нашел KFileItem. Этот класс дает вам все, что вам нужно для значков, типов пантомимы и связанных с ними вещей в KDE. Я уверен, что в gnome есть эквивалент, но это дает доступ на том же уровне, что и приложение QT.
Копирование / вставка приведенного выше хорошего примера (с использованием 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;
}
Может быть, посмотрите на этот код: http://ftp.devil-linux.org/pub/devel/sources/1.2/file-4.23.tar.gz
Это стандартная утилита, используемая в большинстве дистрибутивов Linux/Unix. Вы получите MIME-тип и дополнительную информацию.
Я думаю, что и у Gnome, и у KDE есть свои способы определить это, а также установить значок и стандартное приложение для него.
В любом случае, этот файл-инструмент, вероятно, лучший способ получить тип mime и описание документа. А в некоторых случаях даже некоторые подробности о содержании.
Это даст вам MIME-тип. Это то, что вам нужно, чтобы узнать, как открыть файл. Это отдельные шаги. Файл не говорит вам ни о значке, ни о приложении, с которым можно открыть файл.
Вы можете использовать системный файл "/etc/mime.types". Это также хорошая идея, чтобы сохранить копию вашей программы файла типа MIME. Таким образом, вы не зависите от системы, но в то же время вы должны держать ее достаточно исчерпывающей. Не уверен насчет икон.
Около 8 лет поздно, но все же полезно.
Чтобы получить связанные приложения в KDE, вы можете сделать то, что предложил Джо (используя 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: