[英]How to get the name of a file from a file handle in Windows using C?
我正在嘗試從給定的文件句柄中檢索文件名。
我已經看到GetFileInformationByHandle可能有用,但是它返回的結構不包含任何文件名信息( http://msdn.microsoft.com/zh-cn/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;
}
BOOL GetFileNameFromHandle(HANDLE hFile, TCHAR *pszFileName, const unsigned int uiMaxLen)
{
pszFileName[0]=0;
std::unique_ptr<BYTE[]> ptrcFni(new BYTE[_MAX_PATH * sizeof(TCHAR) + 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;
}
您好,如果您需要從句柄中獲取文件名,則可以閱讀此ms文章http://msdn.microsoft.com/zh-cn/library/aa366789(VS.85).aspx或使用此GetFileInformationByHandleEx
對於Vista和更高版本,請查看GetFinalPathNameByHandle (如mehrdad所寫)
與GetFileInformationByHandleEx相比,它更方便IMO並允許更多自定義,並且消除了分配自定義大小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)。
有一個正確的方法可以在Windows XP上的文件和目錄上執行; 我已經在這里的另一篇文章中對此進行了解釋。
您從哪里獲得文件句柄的? 如果確定它不是命名管道句柄,則可以使用NtQueryObject查詢文件名。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.