【经验】C++|利用 Windows API,通过文件句柄获取文件路径的两种方式
方法一
主要参考博客:根据文件句柄获得文件名(这篇超级清晰,就是有一点点小问题)
通过文件句柄获得文件路径(这篇不是很好用,但是思路大体是一致的)
主要思路:
- 根据
HANDLE创建映射文件,调用GetMappedFileName获得一个DosDevice路径。- 然后
GetLogicaDriveStrings获得盘符字串,依次读取盘符字串获得对应的DosDevice路径,看之前的DosDevice路径中是否有现在的DosDevice路径(strstr)。- 有的话,就拿到盘符字串,把盘字符串和去掉
DosDevice盘符的DosDevice路径拼接;没有的话,就再读取下一个盘符的DosDevice路径,依次这样,直到找到为止。缺点:
- 只能获得自己进程打开的文件,其它进程打开的文件貌似不行。
MapViewOfFile在多线程中会产生冲突,返回错误码6,暂待解决。
#include <windows.h>
#include <psapi.h>
typedef DWORD (WINAPI *MyGetMappedFileName)(HANDLE,LPVOID,LPTSTR,DWORD);
int GetFileNameByHandle(HANDLE hFile,LPSTR buff,DWORD bufSize)
{
HANDLE hfilemap = CreateFileMapping(hFile,NULL,PAGE_READWRITE,NULL,NULL,NULL); // 获取文件映射句柄
if(INVALID_HANDLE_VALUE==hfilemap)
{
printf("CreateFileMapping error: %d\n",GetLastError());
return 0;
}
LPVOID lpmap = MapViewOfFile(hfilemap,FILE_MAP_READ|FILE_MAP_WRITE,NULL,NULL,0); // 获取文件映射对象
if(NULL==lpmap)
{
printf("MapViewOfFile error: %d\n",GetLastError());
return 0;
}
// GetMappedFileName未定义
MyGetMappedFileName GetMappedFileName =(MyGetMappedFileName)GetProcAddress(LoadLibrary("psapi.dll"),"GetMappedFileNameA");
if(GetMappedFileName==NULL)
{
printf("Get 'GetMappedFileName' FuncAddress error.\n");
return 0;
}
char DosStr[MAX_PATH]= {0};
DWORD length = GetMappedFileName(GetCurrentProcess(),lpmap,DosStr,bufSize); // 获取Dos设备名
if(0==length)
{
printf("GetMappedFileName error: %d\n", GetLastError());
return 0;
}
char DosPath[MAX_PATH]= {0};
char DriverString[MAX_PATH]= {0};
if (0 == GetLogicalDriveStrings(MAX_PATH, DriverString)) // 获取电脑的盘符列表
{
printf("GetLogicalDriveStrings error: %d", GetLastError());
return 0;
}
char * p = (char *)DriverString; //p用来指向盘符
do
{
*(p+2)='\0'; //QuerDosDevice第一个参数必须是c:这种类型的,不能有\,所以把\抹掉
if (!QueryDosDevice((LPCTSTR)p, DosPath, MAX_PATH)) // 将盘符映射成DOS设备名
{
printf("QueryDosDrive error: %d\n", GetLastError());
return FALSE;
}
char * q = strstr(DosStr,DosPath); //检测buff中是否有DosDevice中的DosPath,有的话,p指向的那个字串就是要的盘符
if(q!=0)
{
sprintf(buff, "%s%s", p, DosStr+strlen(DosPath)); //找到之后应该把DosPath替换成盘符
return 1;
}
p=p+4; //指针移动到DriverString的下一个盘符处
}
while(*p!=0);
return 0;
}
调用测试:
int main()
{
HANDLE p=CreateFileA("a.txt", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, NULL, NULL);
char m[100000];
GetFileNameByHandle(p, m, sizeof(m));
printf("%s",m);
return 0;
}
结果截图:

方法二
char m[1000]; // 存储路径
int fileNameResult = GetFinalPathNameByHandleA(hFile, m, MAX_PATH, 0); // fileNameResult是路径长度
缺点:不能跨进程获取路径。
可能问题:fileapi.h不存在。(codeblocks中显示不存在,vs2019没有问题)
【经验】C++|利用 Windows API,通过文件句柄获取文件路径的两种方式的更多相关文章
- java中获取文件路径的几种方式
http://xyzroundo.iteye.com/blog/1116159关于绝对路径和相对路径: 绝对路径就是你的主页上的文件或目录在硬盘上真正的路径,(URL和物理路径)例如:C:xyz es ...
- python中获取文件路径的几种方式
# 如果执行文件为E:\aa\bb\aa.py 1.获取当前路径 current_path11 = os.path.abspath(__file__) current_path12 = os.path ...
- 从request中获取文件流的两种方式,配置文件上传大小
原文地址:https://blog.csdn.net/xyr05288/article/details/80692132
- strus2中获取表单数据 两种方式 属性驱动 和模型驱动
strus2中获取表单数据 两种方式 属性驱动 和模型驱动 属性驱动 /** * 当前请求的action在栈顶,ss是栈顶的元素,所以可以利用setValue方法赋值 * 如果一个属性在对象栈,在页面 ...
- SparkStreaming获取kafka数据的两种方式:Receiver与Direct
简介: Spark-Streaming获取kafka数据的两种方式-Receiver与Direct的方式,可以简单理解成: Receiver方式是通过zookeeper来连接kafka队列, Dire ...
- 使用web.xml方式加载Spring时,获取Spring context的两种方式
使用web.xml方式加载Spring时,获取Spring context的两种方式: 1.servlet方式加载时: [web.xml] <servlet> <servlet-na ...
- JavaWeb后台从input表单获取文本值的两种方式
JavaWeb后台从input表单获取文本值的两种方式 #### index.html <!DOCTYPE html> <html lang="en"> & ...
- Express全系列教程之(四):获取Post参数的两种方式
一.关于POST请求 post方法作为http请求很重要的一部分,几乎所有的网站都有用到它,与get不同,post请求更像是在服务器上做修改操作,它一般用于数据资源的更新.相比于get请求,post所 ...
- drupal7 覆写node-type.tpl.php获取字段值的两种方式
字段的机读名称为:field_publication_date <!-- 下面两种方式都可以获取node字段的值--> 出版时间: <?php print date('Y-m-d', ...
- iOS 通过URL网络获取XML数据的两种方式
转载于:http://blog.csdn.net/crayondeng/article/details/8738768 下面简单介绍如何通过url获取xml的两种方式. 第一种方式相对简单,使用NSD ...
随机推荐
- Luogu P2540 NOIP2015提高组 斗地主 加强版 题解 [ 紫 ] [ 深搜 ] [ 剪枝 ]
斗地主:一步一步推性质就能做出来的剪枝题. 这题思路和小木棒的剪枝思路极其相似,剪枝的角度都差不多. 其实大部分搜索剪枝题都是先观察性质,列出性质后选择几个比较关键且代码好写的性质进行剪枝,特别要注意 ...
- windows10专业版代码永久激活
1."Win+R"打开运行对话框,输入命令slmgr.vbs -xpr 可以查看当前系统的激活信息 2. 在电脑图标右键,打开属性,查看自己win10系统版本 3. 在开始菜单右键 ...
- [THUSC2015] 异或运算 题解
学到新思路了:求解 \(k\) 大值时,可以将所有元素放一块一起跑. 考虑到 \(n,q\) 奇小无匹,我们便可以制造一个 \(O(qn\log V)\) 的代码. 那么对于我们不想在时间复杂度中出现 ...
- Java01 - Scanner对象
简介 之前我们学的基本语法中并没有实现程序和人的交互,但是Java给我们提供了这样一个工具类,我们可以获取用户的输入.java.util.Scanner是Java5的新特征,我们可以通过Scanner ...
- MySQL Q&A - [01] root密码忘记了怎么办
题记部分 Windows 场景下 1.先使用管理员身份打开两个命令提示符窗口(winA和winB) 2.在命令提示符窗口winA中将MySQL服务停掉net stop mysql Microsoft ...
- 2024.11.19随笔&联考总结
联考 看到 T1 就知道一定是简单计数题然后发现 \(O(n)\) 可以过于是就大概写了写式子就开写.写的过程中犯了一些低级错误,代码重构了一次才过.耽误的时间比较久.然后开 T2,一眼有一个 \(O ...
- php实现地址跳转的方式
在PHP中,实现地址跳转主要有以下几种方式: 1. 使用 header() 函数 header() 函数用于发送原始的 HTTP 头信息,常用于实现页面跳转. <?php header(&quo ...
- python xlrd xlwr函数 读取excel好文总结
https://www.cnblogs.com/python-robot/p/9958352.html 官网: http://www.python-excel.org/ 好文: https://www ...
- Web前端入门第 14 问:HTML 语义化是什么?
HELLO,这里是大熊学习前端开发的入门笔记. 本系列笔记基于 windows 系统. 语义化:通俗地说,就是让机器可以理解编写出来的 HTML 代码.比如:搜索引擎.屏幕阅读器等. 非语义化写法 网 ...
- 怎么给EXE文件加启动参数
第一步 首先右键单击 exe 文件文件,创建 exe 文件的快捷方式. 第二步 右键单击此快捷方式--属性. 在快捷方式属性界面,点击目标后面的链接. 先打一个空格然后输入参数,然后点击应用按钮.确定 ...