从 C++ 中的扩展中获取 MIME 类型
Posted
技术标签:
【中文标题】从 C++ 中的扩展中获取 MIME 类型【英文标题】:Get a MIME Type from a extension in C++ 【发布时间】:2014-01-05 05:53:24 【问题描述】:在给定文件扩展名的情况下,有什么方法可以在 C++ 中获取 MIME 类型?
我已经阅读了有关 HKEY_CLASSES_ROOT 的信息,但我真的不知道如何使用它。
我想要的是输入:
string extension=".pdf";
string extension2=".avi";
获取输出:
字符串 mimeType="application/pdf"; 字符串 mimeType2="video/x-msvideo";
我知道我可以自己完成,但我想这里已经完成了一些工作。
非常感谢
【问题讨论】:
FindMimeFromData
【参考方案1】:
快到圣诞节了,这样怎么样:
#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
【讨论】:
感谢您抽出宝贵时间罗杰,我得到了意想不到的输出,但会更深入地检查;) @user3009804 好的 - 如果我能提供进一步的帮助,请告诉我(当我仍然感觉圣诞节时)。正如您在问题中使用string
一样,我做了一个非 UNICODE 示例。
下午好,罗杰,我已经尝试了你的非 UNICODE 代码以及 IInspectable 的代码,我发现使用你的代码我可以获得一些扩展的 MIME 类型,但我不能其他扩展。例如,我知道该应用程序是未知的,扩展名为:.avi、.mp3。 .mp4, .wmv, .rar, .log, .... 你知道有什么问题吗?谢谢大家;)
@user3009804 - 它只是在读取注册表,因此请使用 Regedit.exe 查看例如HKEY_CLASSES_ROOT\.mp3
并查看是否有Content Type
键。如果有,可能是权限问题。 HKEY_CLASSES_ROOT\MIME\Database\Content Type
也有反向查询。
@user3009804 你知道将我的方法与 IInspectable 结合起来可能是值得的——据我所知,他只会给出 26 个(左右)预定义类型,而我只会给出扩展名所在的那些通过应用程序注册。如果一个失败,另一个可能会成功。【参考方案2】:
最简单的解决方案是调用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
【讨论】:
非常感谢您的代码!我已经尝试使用几个扩展名,其中一些有效,而另一些则无效,例如 .avi(是的,不明白 .avi 怎么不能工作)、.mov、.mp3、.mp4 等。 mpeg, .vmw, ...你知道会发生什么吗?非常感谢! 从我在一个紧密循环中进行的一些测试中(使用任务管理器查看while (true) )
)我同意CoTaskMemFree
。以上是关于从 C++ 中的扩展中获取 MIME 类型的主要内容,如果未能解决你的问题,请参考以下文章