Получить MIME-тип из расширения в C ++

0

Есть ли способ получить MIME-тип в C++ с учетом расширения файла?

Я читал о HKEY_CLASSES_ROOT, но я честно понятия не имею, как его использовать.

То, что я хочу, имеет в качестве входных данных:

 string extension=".pdf"; 
 string extension2=".avi";

Получить как выход:

string mimeType = "application/pdf";
string mimeType2 = "video/x-msvideo";

Я знаю, что могу сделать это сам, но я думаю, что здесь уже есть какая-то работа.

большое спасибо

Теги:
winapi

2 ответа

3
Лучший ответ

Как это почти Рождество, как насчет этого:

#include <Windows.h>
#include <string>

using namespace std;

string GetMimeType(const string &szExtension)
{
    // return mime type for extension
    HKEY hKey = NULL;
    string szResult = "application/unknown";

    // open registry key
    if (RegOpenKeyEx(HKEY_CLASSES_ROOT, szExtension.c_str(), 
                       0, KEY_READ, &hKey) == ERROR_SUCCESS)
    {
        // define buffer
        char szBuffer[256] = {0};
        DWORD dwBuffSize = sizeof(szBuffer);

        // get content type
        if (RegQueryValueEx(hKey, "Content Type", NULL, NULL, 
                       (LPBYTE)szBuffer, &dwBuffSize) == ERROR_SUCCESS)
        {
            // success
            szResult = szBuffer;
        }

        // close key
        RegCloseKey(hKey);
    }

    // return result
    return szResult;
}

int main(int argc, char* argv[])
{
    string szExt1 = ".pdf";
    string szExt2 = ".avi";

    string szMime1 = GetMimeType(szExt1);
    string szMime2 = GetMimeType(szExt2);

    printf("%s = %s\n%s = %s\n", szExt1.c_str(), szMime1.c_str(), 
        szExt2.c_str(), szMime2.c_str());

    return 0;
}

В моей системе он дает следующий результат:

.pdf = приложение /pdf
.avi = видео /avi

  • 0
    спасибо за ваше время, Роджер, я получаю неожиданные результаты, но проверю это глубже;)
  • 1
    @ user3009804 Хорошо - просто дай мне знать, если я смогу помочь дальше (пока я все еще чувствую себя христовым). Поскольку вы использовали string в своем вопросе, я привел пример не в Юникоде.
Показать ещё 5 комментариев
5

Самое простое решение включает вызов FindMimeFromData:

#include <urlmon.h>
#pragma comment( lib, "urlmon" )

std::wstring MimeTypeFromString( const std::wstring& str ) {

    LPWSTR pwzMimeOut = NULL;
    HRESULT hr = FindMimeFromData( NULL, str.c_str(), NULL, 0,
                                   NULL, FMFD_URLASFILENAME, &pwzMimeOut, 0x0 );
    if ( SUCCEEDED( hr ) ) {
        std::wstring strResult( pwzMimeOut );
        // Despite the documentation stating to call operator delete, the
        // returned string must be cleaned up using CoTaskMemFree
        CoTaskMemFree( pwzMimeOut );
        return strResult;
    }

    return L"";
}

Следующее приложение

int _tmain( int argc, _TCHAR* argv[] ) {
    std::wcout << L".pdf: " << MimeTypeFromString( L".pdf" ) << std::endl;
    std::wcout << L".avi: " << MimeTypeFromString( L".avi" ) << std::endl;

    return 0;
}

производит этот вывод в моей системе:

.pdf: application/pdf
.avi: video/avi
  • 0
    Большое спасибо за ваш код! Я пробовал использовать несколько расширений, и в некоторых из них работает, а в некоторых нет, например .avi (да, не понимаю, как не работает .avi), .mov, .mp3, .mp4,. mpeg, .vmw, ... вы знаете, что может происходить? большое спасибо!
  • 0
    Из некоторых тестов, которые я сделал в тесном цикле (некоторое while (true) {}) , просматривая диспетчер задач), я согласен с CoTaskMemFree .

Ещё вопросы

Сообщество Overcoder
Наверх
Меню