【经验】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 P9180 [COCI2022-2023#5] Slastičarnica 题解 [ 蓝 ] [ 区间 dp ] [ dp 状态优化 ] [ 前缀和优化 ]
Slastičarnica:非常好的区间 dp 题. 暴力 不难设计出暴力状态:\(dp_{q,i,j}\) 表示进行到第 \(q\) 次操作,剩下区间 \([i,j]\) 是否可行. 直到全部状态都 ...
- 超详细,DeepSeep 接入PyCharm实现AI编程!(支持本地部署DeepSeek及官方DeepSeek接入),建议收藏!
在当今数字化时代,AI编程助手已成为提升开发效率的利器.DeepSeek作为一款强大的AI模型,凭借其出色的性能和开源免费的优势,成为许多开发者的首选.今天,就让我们一起探索如何将DeepSeek接入 ...
- 了解了这些你就是一位优秀的CTO
spring cloud 分布式 Ngix协议层做阻断应射处理 SpringBoot 容器+MVC框架 SpringSecurity 认证和授权框架 MyBatis ORM框架 Swagger-UI ...
- CF2067D Object Identification
CF2067D - Object Identification 题目大意 有一个对你公开的 \(x\) 数组和一个对你隐藏的 \(y\) 数组,保证没有任何两个相同的 \(\{x_i, y_i\}\) ...
- mysql : 第5章 数据库的安全性
-- 创建用户CREATE USER utest@localhost IDENTIFIED BY 'temp';-- 查看所有用户SELECT * FROM mysql.user;-- 查看表级权限S ...
- 【Matlab】输出变量内容到xls文件
版本: matlab 2017a 功能:将矩阵输出一个excel文件 代码: function [ statu ] = write2xls( x,filename,sheet) % 返回值: % 1 ...
- Oracle 内存(SGA,PGA)详细介绍
一.名词解释(1)SGA:SystemGlobal Area是OracleInstance的基本组成部分,在实例启动时分配;系统全局域SGA主要由三部分构成:共享池.数据缓冲区.日志缓冲区.(2)共享 ...
- Qt/C++开发经验小技巧311-315
关于流媒体推拉流延时的几点说明. 经常看到一些流媒体相关的程序,号称零延迟,不用怀疑,这肯定吹牛逼的. 搞音视频开发,有个核心的指标就是实时性,也就是延迟多少毫秒,这个问题问的也是最多的. 音视频文件 ...
- 【SpringCloud】SpringCloud Alibaba Nacos服务注册和配置中心
SpringCloud Alibaba Nacos服务注册和配置中心 感悟 注意:凡是cloud里面,你要开哪个组件,新加哪个注解,第一个就是启动,如@EnableFeignClients,第二个就是 ...
- 【SpringCloud】Consul服务注册与发现
Consul服务注册与发现 Consul简介 是什么 https://www.consul.io/intro/index.html Consul是一开源的分布式服务发现和配置管理系统,由HashiCo ...