2

我正在尝试从给定的文件句柄中检索文件名。

我已经看到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;
}
4

5 回答 5

2

嗨,如果您需要句柄中的文件名,您可以阅读这篇 ms 文章http://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx 或使用此 GetFileInformationByHandleEx

于 2010-11-28T09:08:48.887 回答
2
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;
}
于 2015-07-21T10:10:19.407 回答
1

有一种正确的方法可以在 Windows XP 上运行,无论是文件还是目录;我在这里的另一篇文章中对此进行了解释。

于 2011-03-13T01:55:14.027 回答
1

对于 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)。

于 2017-11-13T13:09:33.593 回答
0

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

于 2010-11-28T11:24:10.150 回答