获取ARX文件路径

作者: admin 分类: C++,CAD,ObjectARX 发布时间: 2020-10-30 20:11

TCHAR szPath[256];

GetModuleFileName(_hdllInstance, szPath, sizeof(szPath));

*(_tcsrchr(szPath, '\\')) = 0; // 将最后一个\所在的位置修改为\0

_hdllInstance=NULL时,得到的路径就是acad.exe的路径,不清楚为什么_hdllInstance会为NULL


这个更好用

得到ARX程序当前的路径

BOOL GetArxPath(CString &path)
{
CString ArxPath;
ACHAR modulePath[512];//取应用程序路径
//CString FileName = acedGetAppName(); //功能与下个函数重复,可能为空,不可靠
HMODULE hModule = NULL;
MEMORY_BASIC_INFORMATION mbi;

if(::VirtualQuery(GetArxPath, &mbi, sizeof(mbi)) != 0)
{
hModule = (HMODULE) mbi.AllocationBase;
}
DWORD pathLength = GetModuleFileName(hModule, modulePath, 512);
if (pathLength)
{
ArxPath=modulePath;
int rs=ArxPath.ReverseFind('//'); //查找最后一个'//'的位置
path = ArxPath.Left(rs); //去掉文件名
return TRUE;
}
return FALSE;
}
————————————————
版权声明:本文为CSDN博主「无敌鼓舞」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/tong794729500/article/details/79201641




作者:cdinten,http://bbs.mjtd.com/thread-112050-1-1.html

使用ObjectARX开发的插件,可能并不只有ARX文件,还会有其他的一些数据库文件、图片等资源文件,通常这些文件会和ARX文件放在同一个目录下,但是在AutoCAD加载了ARX文件之后,如何定位获取这些文件的路径呢?如果是dll文件,在DllMain函数的第一个参数就是其模块句柄,而ARX的入口函数AcRxEntryPoint中并没有带这个参数,只能自己想办法了。这里提供了几种获取ARX文件路径的方法:

void GetMyPath()
{
    ACHAR path[MAX_PATH]=L"";
    HMODULE hMe;
    //ARX文件的名称
    hMe=GetModuleHandle(L"ArxHello.arx");
    if(hMe==NULL)
    {
        acutPrintf(L"\n获取模块句柄失败\n");
        return;
    }
    GetModuleFileName(hMe,path,MAX_PATH);
    //文件的绝对路径
    acutPrintf(L"\n%s\n",path);
    //文件所在文件夹
    ACHAR* pt=wcsrchr(path,L'\\');
    *(pt+1)='\0';
    acutPrintf(L"\n%s\n",path);
}

这个函数需要windows.h头文件的支持,实际上是调用了系统API,但是这个函数有个小问题,就是GetModuleHandle函数中的参数,必须是我们的ARX文件名,一旦ARX文件被重命名,这个函数就回调用失败,出现“获取模块句柄失败”的提示。另一个根号的方法是,使用增强版的获取模块句柄函数,这个系统API就是GetModuleHandleEx,可以在无需知道ARX文件名的情况下获取文件路径,但是使用时要格外小心,先贴一个出来给大家看看:

void GetMyPath()
{
ACHAR path[MAX_PATH]=L"";
HMODULE hMe;
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,(ACHAR*)GetMyPath,&hMe);
if(hMe==NULL)
{
acutPrintf(L"\n获取模块句柄失败\n");
return;
}
GetModuleFileName(hMe,path,MAX_PATH);
//文件的绝对路径
acutPrintf(L"\n%s\n",path);
//文件所在文件夹
ACHAR* pt=wcsrchr(path,L'\\');
*(pt+1)='\0';
acutPrintf(L"\n%s\n",path);
}

这个函数运行之后也能获取路径,而且无论我们的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编程相关的文章,和大家共同交流讨论,也请大家不吝赐教,共同进步。

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!

发表评论

标签云