2010-08-17 110 views
0

我想显示给定文件名(基于扩展名)使用AssocQueryKey() API函数的文件类型。 问题是有时候返回错误的HKEY值。例如,以下函数在win 7 ultimate x64上正常工作,但是在我的win xp x86机器上有一些扩展名(例如“.mp3”)失败(其他扩展工作正常)。 即使 “成功”,并返回S_OK,GetLastError()AssocQueryKey()调用1008 ALWAYS:从Windows注册表获取文件类型在c + +

// Return STL string representation of file type from windows registry 
stlstring GetFileTypeFromRegistry(const stlstring& m_filename) 
{ 
CRegKey reg; 
HKEY key = {0}; 
stlstring s; 
//Get file extension 
LPCTSTR fExt = PathFindExtension(m_filename.c_str()); 
if(AssocQueryKey(NULL, ASSOCKEY_CLASS, fExt, TEXT(""), &key) != S_OK) 
    DisplayError(_T("AssocQueryKey != S_OK"), GetLastError()); 
else 
    DisplayError(_T("AssocQueryKey == S_OK"), GetLastError()); 

if(reg.Open (key, NULL, KEY_QUERY_VALUE) != ERROR_SUCCESS){ 
    reg.Close(); 
    DisplayError((LPTSTR)fExt); 
    return s; 
} 
//DWORD out = 0; 
/*WCHAR *h = new WCHAR[1024]; 
ZeroMemory(h, sizeof(h)); 
AssocQueryStringByKey(0, ASSOCSTR_EXECUTABLE, HKEY_CLASSES_ROOT, NULL, h, &out); 
//MessageBox(0,_T("gbtbb"),h,MB_OK); 
delete[] h;*/ 
ULONG m_sz = 256; 
//if(reg.QueryStringValue(NULL, NULL, &m_sz) == ERROR_SUCCESS){ 

    TCHAR *m_regstring = new TCHAR[m_sz + 1]; 
    if(reg.QueryStringValue(NULL, m_regstring, &m_sz) == ERROR_SUCCESS){ 
    //DisplayError(_T("")); 
    s += m_regstring; 
    /*delete[] m_regstring; m_regstring = NULL; 
    reg.Close(); 
    return s;*/ 
    } else { 
    DisplayError(_T("CRegKey::QueryStringValue()"), GetLastError()); 
    } 
    s += m_regstring; 
    delete[] m_regstring; m_regstring = NULL; 
    reg.Close(); 
    return s; 
/*} 
reg.Close(); 
return s;*/ 
} 

对此有何想法?这个函数来自一个由Windows资源管理器加载的DLL,如果这很重要的话可以实现IQueryInfo::GetInfoTip()

+0

当你说“无法像” .MP3' 一些扩展”,你的意思是,它返回'S_OK'但'HKEY'不正确的注册表位置?请注意,当没有错误返回时检查'GetLastError()'的值是没有意义的 - 最后的错误代码通常是由您调用的API调用的函数偶然设置的。它的值是没有意义的,除非你得到一个错误发生的指示(换句话说,成功的API不需要保持最后一个错误的原始值或将其设置为0)。 – 2010-08-17 17:24:26

+0

第一个参数的NULL没有意义。此处需要定义失败。 – 2010-08-17 17:40:56

回答

2

对于直接返回错误代码的函数,您不应该使用GetLastErrorAssocQueryKey的MSDN页面显示“如果成功返回S_OK,否则返回COM错误值”,这意味着您已经在返回值中获得错误代码。

如果您只是想获取文件类型信息,那么有一个更简单的解决方案:SHGetFileInfo。这是非常简单的使用,像这样:

SHFILEINFO shfi; 
SHGetFileInfo(filename, 0, &shfi, sizeof(shfi), SHGFI_TYPENAME | SHGFI_USEFILEATTRIBUTES); 
// shfi.szTypeName now contains the file type string of the given filename