明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 4670|回复: 6

获取ARX文件路径

[复制链接]
发表于 2014-11-11 22:45:42 | 显示全部楼层 |阅读模式
本帖最后由 cdinten 于 2014-11-11 22:49 编辑

使用ObjectARX开发的插件,可能并不只有ARX文件,还会有其他的一些数据库文件、图片等资源文件,通常这些文件会和ARX文件放在同一个目录下,但是在AutoCAD加载了ARX文件之后,如何定位获取这些文件的路径呢?如果是dll文件,在DllMain函数的第一个参数就是其模块句柄,而ARX的入口函数AcRxEntryPoint中并没有带这个参数,只能自己想办法了。这里提供了几种获取ARX文件路径的方法:
  1. void GetMyPath()
  2. {
  3.     ACHAR path[MAX_PATH]=L"";
  4.     HMODULE hMe;
  5.     //ARX文件的名称
  6.     hMe=GetModuleHandle(L"ArxHello.arx");
  7.     if(hMe==NULL)
  8.     {
  9.         acutPrintf(L"\n获取模块句柄失败\n");
  10.         return;
  11.     }
  12.     GetModuleFileName(hMe,path,MAX_PATH);
  13.     //文件的绝对路径
  14.     acutPrintf(L"\n%s\n",path);
  15.     //文件所在文件夹
  16.     ACHAR* pt=wcsrchr(path,L'\\');
  17.     *(pt+1)='\0';
  18.     acutPrintf(L"\n%s\n",path);
  19. }

这个函数需要windows.h头文件的支持,实际上是调用了系统API,但是这个函数有个小问题,就是GetModuleHandle函数中的参数,必须是我们的ARX文件名,一旦ARX文件被重命名,这个函数就回调用失败,出现“获取模块句柄失败”的提示。另一个根号的方法是,使用增强版的获取模块句柄函数,这个系统API就是GetModuleHandleEx,可以在无需知道ARX文件名的情况下获取文件路径,但是使用时要格外小心,先贴一个出来给大家看看:
  1. void GetMyPath()
  2. {
  3. ACHAR path[MAX_PATH]=L"";
  4. HMODULE hMe;
  5. GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,(ACHAR*)GetMyPath,&hMe);
  6. if(hMe==NULL)
  7. {
  8. acutPrintf(L"\n获取模块句柄失败\n");
  9. return;
  10. }
  11. GetModuleFileName(hMe,path,MAX_PATH);
  12. //文件的绝对路径
  13. acutPrintf(L"\n%s\n",path);
  14. //文件所在文件夹
  15. ACHAR* pt=wcsrchr(path,L'\\');
  16. *(pt+1)='\0';
  17. acutPrintf(L"\n%s\n",path);
  18. }

这个函数运行之后也能获取路径,而且无论我们的ARX改成什么名字,放在哪里,都能正确显示路径。但是有个问题就是,运行过该函数之后,再使用命令将ARX卸载,虽然AutoCAD提示是成功卸载了,但是ARX文件还是被AutoCAD打开,似乎有内存没有被释放,试图删除ARX文件会失败,不知道是怎么回事吧?因为GetModuleHandleEx中出现了问题。
仔细阅读了MSDN中的相关条款,GetModuleHandleEx在调用的时候,会让引用计数器加1,所以第一个参数才有GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,就是不让引用计数器加1,因此,如果不带该标志位的话,虽然AutoCAD看似卸载了该动态链接库文件,但是该动态链接库的引用计数还是1,所以,确实删不掉。
找到了问题之后,解决起来就方便多了,这里有两种方式可供选择:
A. 将GetModuleHandleEx的第一个参数改为6(也就是GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT)
B. GetModuleHandleEx的参数保持不变,在GetModuleFileName函数之后,加一句“FreeLibrary(hMe);”,也就是释放库函数。

最后,借个宝地做做广告,本人的博客:http://379910987.blog.163.com/ ,不定期发布一些个人学习二次开发和Windows编程相关的文章,和大家共同交流讨论,也请大家不吝赐教,共同进步。
发表于 2014-12-31 20:14:53 | 显示全部楼层
写的不错,赞一个!
发表于 2015-1-1 10:32:27 | 显示全部楼层
恩,不错,赞一个
发表于 2015-1-3 18:16:48 | 显示全部楼层
太棒了,解决了大问题,谢谢楼主。
发表于 2015-1-4 13:37:16 | 显示全部楼层
太好了,针对问题能够找到本质。
发表于 2015-1-4 14:57:45 | 显示全部楼层
CString ArxPath = acedGetAppName();
或者:
ACHAR modulePath[512];
DWORD pathLength = GetModuleFileName(_hdllInstance, modulePath, 512);
CString ArxPath=modulePath;

点评

软件里的arx文件怎样加壳加密后实现一机一码? 公司里的某些软件需要arx文件覆盖替换后才可以使用,为了防止外泄外传,怎样给软件里的arx文件加壳加密后实现一机一码?  发表于 2015-8-27 10:09
发表于 2015-8-27 10:08:41 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-25 04:43 , Processed in 0.179248 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表