如何从Windows中使用C的文件句柄获取文件的名称?

我试图从给定的文件句柄检索文件名。

我已经看到, GetFileInformationByHandle可能是有用的,但它返回的结构不包含任何文件名信息( http://msdn.microsoft.com/en-us/library/aa363788%28v=VS.85%29.aspx )。

我怎样才能做到这一点?

编辑:

我已经尝试安装Windows FileID API来获取GetFileInformationByHandleEx在Windows XP上工作。 但是,当包含fileextd.h我得到以下错误

c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(16) : error C2011: '_FILE_INFO_BY_HANDLE_CLASS' : 'enum' type redefinition c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(13900) : see declaration of '_FILE_INFO_BY_HANDLE_CLASS' c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(32) : error C2011: '_FILE_BASIC_INFO' : 'struct' type redefinition c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(13917) : see declaration of '_FILE_BASIC_INFO' c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(40) : error C2011: '_FILE_STANDARD_INFO' : 'struct' type redefinition c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(13925) : see declaration of '_FILE_STANDARD_INFO' c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(48) : error C2011: '_FILE_NAME_INFO' : 'struct' type redefinition c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(13933) : see declaration of '_FILE_NAME_INFO' c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(53) : error C2011: '_FILE_RENAME_INFO' : 'struct' type redefinition c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(13938) : see declaration of '_FILE_RENAME_INFO' c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(60) : error C2011: '_FILE_ALLOCATION_INFO' : 'struct' type redefinition c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(13945) : see declaration of '_FILE_ALLOCATION_INFO' c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(64) : error C2011: '_FILE_END_OF_FILE_INFO' : 'struct' type redefinition c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(13949) : see declaration of '_FILE_END_OF_FILE_INFO' c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(68) : error C2011: '_FILE_STREAM_INFO' : 'struct' type redefinition c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(13953) : see declaration of '_FILE_STREAM_INFO' c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(76) : error C2011: '_FILE_COMPRESSION_INFO' : 'struct' type redefinition c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(13961) : see declaration of '_FILE_COMPRESSION_INFO' c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(85) : error C2011: '_FILE_ATTRIBUTE_TAG_INFO' : 'struct' type redefinition c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(13970) : see declaration of '_FILE_ATTRIBUTE_TAG_INFO' c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(90) : error C2011: '_FILE_DISPOSITION_INFO' : 'struct' type redefinition c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(13975) : see declaration of '_FILE_DISPOSITION_INFO' c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(94) : error C2011: '_FILE_ID_BOTH_DIR_INFO' : 'struct' type redefinition c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(13979) : see declaration of '_FILE_ID_BOTH_DIR_INFO' c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(130) : error C2011: '_FILE_ID_TYPE' : 'enum' type redefinition c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(14026) : see declaration of '_FILE_ID_TYPE' c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(135) : error C2011: 'FILE_ID_DESCRIPTOR' : 'struct' type redefinition c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(14032) : see declaration of 'FILE_ID_DESCRIPTOR' c:\documents and settings\lab\documenti\visual studio 2008\projects\sandbox\sandbox\funcs_files.cpp(26) : error C2079: 'lpFileInformation' uses undefined struct '_FILE_NAME_INFO' c:\documents and settings\lab\documenti\visual studio 2008\projects\sandbox\sandbox\funcs_files.cpp(35) : error C2228: left of '.FileName' must have class/struct/union type is 'int' 

从下面的代码:

 #include <windows.h> #include <fileextd.h> LPVOID GetFileNameFromHandle(HANDLE hFile) { FILE_NAME_INFO lpFileInformation; BOOL bWorked; bWorked = GetFileInformationByHandleEx( hFile, FileNameInfo, &lpFileInformation, sizeof(FILE_NAME_INFO)); return lpFileInformation.FileName; } 

嗨,如果你需要从处理文件的名称,你可以阅读这个MS文章http://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx或使用GetFileInformationByHandleEx

 BOOL GetFileNameFromHandle(HANDLE hFile, TCHAR *pszFileName, const unsigned int uiMaxLen) { pszFileName[0]=0; std::unique_ptr<TCHAR> ptrcFni(new TCHAR[_MAX_PATH + sizeof(FILE_NAME_INFO)]); FILE_NAME_INFO *pFni = reinterpret_cast<FILE_NAME_INFO *>(ptrcFni.get()); BOOL b = GetFileInformationByHandleEx(hFile, FileNameInfo, pFni, sizeof(FILE_NAME_INFO) + (_MAX_PATH * sizeof(TCHAR)) ); if ( b ) { #ifdef _UNICODE wcsncpy_s(pszFileName, min(uiMaxLen, (pFni->FileNameLength / sizeof(pFni->FileName[0])) + 1 ), pFni->FileName, _TRUNCATE); #else strncpy_s(pszFileName, min(uiMaxLen, (pFni->FileNameLength / sizeof(pFni->FileName[0])) + 1), CW2A(pFni->FileName), _TRUNCATE); #endif } return b; } 

有一个正确的方法来做到这一点,在Windows XP上,在文件和目录; 我在另一个帖子里解释过

你从哪里得到文件句柄? 如果你确定它不是一个命名管道句柄,你可以使用NtQueryObject来查询文件名。

对于Vista和后来看看GetFinalPathNameByHandle (就像mehrdad写的)

这是比较方便的国际海事组织,并允许更多的定制比GetFileInformationByHandleEx ,它消除了分配自定义大小FILE_NAME_INFO结构的麻烦。

例:

 DWORD size = GetFinalPathNameByHandleW(handle, NULL, 0, VOLUME_NAME_DOS); if (size == 0) return L"(NOT FOUND)"; std::wstring fname(size, L'0'); size = GetFinalPathNameByHandleW(handle, &fname.front(), size, VOLUME_NAME_DOS); 

注意 ,它会在返回的名字前加上\\?\

(我使用C ++ std :: wstring来避免C样板进行内存处理,使用malloc来满足您的需求)。