Winapi 如何获得拼写正确的当前目录?

Winapi 如何获得拼写正确的当前目录?,winapi,Winapi,我可以使用GetCurrentDirectory()获取当前目录的路径,但它似乎总是继承PowerShell当前目录的拼写。例如,假设在卷D:上有一个名为Test\MyProgram的目录结构。现在,如果我在PowerShell中执行此操作: cd D:/test/myprogram ./myprogram 然后GetCurrentDirectory()将返回D:\test\myprogram作为当前目录,因为这是我传递给cd的内容,但如上所述,实际上是D:\test\myprogram

我可以使用
GetCurrentDirectory()
获取当前目录的路径,但它似乎总是继承PowerShell当前目录的拼写。例如,假设在卷
D:
上有一个名为
Test\MyProgram
的目录结构。现在,如果我在PowerShell中执行此操作:

 cd D:/test/myprogram
 ./myprogram
然后
GetCurrentDirectory()
将返回
D:\test\myprogram
作为当前目录,因为这是我传递给
cd
的内容,但如上所述,实际上是
D:\test\myprogram


当然,大写和小写字符在Windows上没有什么区别,但仍然是:如何用正确的拼写获得当前目录的真实名称

调用
GetFileInformationByHandleEx
传递文件句柄和
FileNameInfo
作为
FileInformationClass
参数。您需要为路径上的每个组件执行此操作

调用
GetFileInformationByHandleEx
传递文件句柄和
FileNameInfo
作为
FileInformationClass
参数。您需要为路径上的每个组件执行此操作

只有文件系统知道如何在内部存储文件名。所以唯一的方法是打开路径句柄,然后查询文件系统中的路径。比如说通过api。但请注意,开始时需要有正确的路径,否则无法打开文件。所以我认为这样做通常是没有意义的

// here path returned by call GetCurrentDirectoryW

HANDLE hFile = CreateFileW(path, 0, 0, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);

if (hFile != INVALID_HANDLE_VALUE)
{
    if (PWSTR szFilePath = new WCHAR[MAXSHORT])
    {
        if (GetFinalPathNameByHandle(hFile, szFilePath, MAXSHORT, FILE_NAME_NORMALIZED))
        {
            DbgPrint("%S\n", szFilePath);
        }
        delete [] szFilePath;
    }
    CloseHandle(hFile);
}

还请注意,我们可以使用
文件名\u OPENED
代替
文件名\u NORMALIZED
。这里的区别是,在使用
文件名\u规范化的情况下,
,对文件系统进行额外查询。此信息类位于ReFS和NTFS文件系统上。其他文件系统返回
状态\u无效\u设备\u请求
。如果说真的,我不知道什么时候返回不同的名字。因此,在练习调用时,打开
文件名
会加快工作速度,并给出与规范化的
文件名

相同的结果,只有文件系统知道如何在内部存储文件名。所以唯一的方法是打开路径句柄,然后查询文件系统中的路径。比如说通过api。但请注意,开始时需要有正确的路径,否则无法打开文件。所以我认为这样做通常是没有意义的

// here path returned by call GetCurrentDirectoryW

HANDLE hFile = CreateFileW(path, 0, 0, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);

if (hFile != INVALID_HANDLE_VALUE)
{
    if (PWSTR szFilePath = new WCHAR[MAXSHORT])
    {
        if (GetFinalPathNameByHandle(hFile, szFilePath, MAXSHORT, FILE_NAME_NORMALIZED))
        {
            DbgPrint("%S\n", szFilePath);
        }
        delete [] szFilePath;
    }
    CloseHandle(hFile);
}

还请注意,我们可以使用
文件名\u OPENED
代替
文件名\u NORMALIZED
。这里的区别是,在使用
文件名\u规范化的情况下,
,对文件系统进行额外查询。此信息类位于ReFS和NTFS文件系统上。其他文件系统返回
状态\u无效\u设备\u请求
。如果说真的,我不知道什么时候返回不同的名字。因此,在练习调用时,打开
文件名
会更快一些,并给出与
文件名
相同的结果。我们需要首先打开文件,然后使用
文件名\u规范化的
调用
GetFinalPathNameByHandle
。这只需要做一次,而不是每个组件。但无论如何,我并不认为规范化有什么大的意义,比如
GetFileInformationByHandleEx
——它只返回文件系统内的文件路径——没有设备名(或者驱动程序字母,如果需要)——如果这是可以的话——可以更好地使用这个api。如果我们需要设备的完整路径-需要使用
GetFinalPathNameByHandle
不要认为这是最好的。我们需要首先打开文件,然后使用
文件名\u规范化的
调用
GetFinalPathNameByHandle
。这只需要做一次,而不是每个组件。但无论如何,我并不认为规范化有什么大的意义,比如
GetFileInformationByHandleEx
——它只返回文件系统内的文件路径——没有设备名(或者驱动程序字母,如果需要)——如果这是可以的话——可以更好地使用这个api。如果我们需要设备的完整路径-需要使用
GetFinalPathNameByHandle
做什么?您可以打开文件夹,然后查询文件系统的名称,比如说通过
GetFinalPathNameByHandle
,但为了什么?您在开始时拥有的名称也正确,否则您无法打开文件夹并查询其“真实”名称,原因是什么?您可以打开文件夹,然后查询文件系统的名称,比如说通过
GetFinalPathNameByHandle
,但为了什么?您在开始时的名称也正确,否则您无法打开文件夹并查询“真实”名称。谢谢,这很好。不过,需要注意的是,它至少需要Windows Vista。谢谢,这很好用。不过,应该注意的是,它至少需要WindowsVista。