如何获取当前dll或exe模块所在路径?

        有时我们需要在当前运行的dll或exe模块中去动态加载当前模块同路径中的另一个库,或者启动当前模块同路径中的另一个exe程序,一般需要获取当前模块的路径,然后去构造同路径下目标模块的绝对路径,然后通过该绝对路径去加载或启动该目标进程。

       最近我们在一个SDK项目中遇到了类似的问题,客户的Java程序通过JNI调用我们的C++ 动态库umssdk.dll,然后在该dll动态库初始化的接口中自动启动同路径下的XxLauncher.exe程序。umssdk.dll库中启动XxLauncher.exe程序的代码如下:

// 启动XxLauncher.exe
void StartExe()
{TCHAR achLog[256] = { 0 };TCHAR szPath[MAX_PATH] = { 0 };TCHAR *p = szPath;// 获取当前模块的路径::GetModuleFileName(NULL, szPath, MAX_PATH);// 用当前模块的路径去构造目标模块XxLauncher.exe的绝对路径,然后使用该绝对路径去启动该exe程序p += _tcslen(szPath);while (*p-- != _T('\\'));*(p + 2) = 0;_tcscat(szPath, _T("XxLauncher.exe"));SHELLEXECUTEINFO si;RtlZeroMemory(&si, sizeof(SHELLEXECUTEINFO));si.cbSize = sizeof(SHELLEXECUTEINFO);si.lpFile = szPath;si.nShow = SW_SHOWNORMAL;si.lpVerb = _T("open");BOOL bRet = ShellExecuteEx(&si);if (!bRet) {int nErr = GetLastError();int nHInsVal = (int)si.hInstApp;}
}

代码中调用API函数GetModuleFileName获取当前dll模块的路径,然后用当前模块的路径去构造目标模块XxLauncher.exe的绝对路径,然后使用该绝对路径去启动该exe程序。

       Java主程序通过JNI加载的umssdk.dll路径如下所示,要启动的程序XxLauncher.exe也在umssdk.dll同一个路径中,如下所示:

但客户Java程序在启动umssdk.dll库时,弹错如下的报错提示框:

居然跑到D:\aa_tools\5.0_idx_64\eclipse\jre\bin\路径下去启动XxLauncher.exe程序,难道这是受当前的工作路径影响导致的?

       于是去查看启动XxLauncher.exe程序代码,代码中使用API函数GetModuleFileName去获取当前加载的umssdk.dll路径,隐约中想起来,当给GetModuleFileName函数第一个参数传递NULL时,GetModuleFileName获取的好像是启动当前进程的主程序路径,即Java主程序的路径。于是,到MSDN上查看GetModuleFileName函数的说明,如下:

当第一个参数传NULL时,GetModuleFileName获取的是确实是启动当前进程的主程序路径,就是Java主程序的路径。

        如果要获取当前umssdk.dll库的路径,应该传入umssdk.dll模块的实例句柄,那如何获取umssdk.dll实例句柄呢?dll库的实例句柄可以在dll库的入口函数DllMain中获取,如下所示:

HMODULE g_hDLLInstance = NULL;BOOL APIENTRY DllMain( HMODULE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved)
{g_hDLLInstance = hModule;switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:case DLL_THREAD_ATTACH:case DLL_THREAD_DETACH:case DLL_PROCESS_DETACH:break;}return TRUE;
}

即定义一个全局实例句柄变量g_hDLLInstance,在DllMain中将当前dll模块的句柄保存下来,然后在调用GetModuleFileName函数时使用该g_hDLLInstance变量接口,修改后的代码如下所示:

// 启动XxLauncher.exe
void StartExe()
{TCHAR achLog[256] = { 0 };TCHAR szPath[MAX_PATH] = { 0 };TCHAR *p = szPath;// 获取当前模块的路径::GetModuleFileName(g_hDLLInstance, szPath, MAX_PATH);// 用当前模块的路径去构造目标模块XxLauncher.exe的绝对路径,然后使用该绝对路径去启动该exe程序p += _tcslen(szPath);while (*p-- != _T('\\'));*(p + 2) = 0;_tcscat(szPath, _T("XxLauncher.exe"));SHELLEXECUTEINFO si;RtlZeroMemory(&si, sizeof(SHELLEXECUTEINFO));si.cbSize = sizeof(SHELLEXECUTEINFO);si.lpFile = szPath;si.nShow = SW_SHOWNORMAL;si.lpVerb = _T("open");BOOL bRet = ShellExecuteEx(&si);if (!bRet) {int nErr = GetLastError();int nHInsVal = (int)si.hInstApp;}
}

       如果是exe模块,如何获取当前exe模块的实例句柄呢?其实很简单,在WinMain函数中记录一下即可,如下所示:

int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR    lpCmdLine,int       nCmdShow)
{UNREFERENCED_PARAMETER(hPrevInstance);// 此处将当前应用程序的实例保存到g_hInstance,因为有的API调用时要使用该参数g_hInstance = hInstance;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/25299.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高速USB转串口芯片CH343

CH343封装 截止目前,主要封装有 SOP16: CH343G QFN16: CH343P ESSOP10: CH343K,截止24年6月未生产 CH343串口速度 最高串口速度: 6Mbps,比CH340的2M,快3倍 1、概述 参考版本:1E CH343 是一个 USB 总线的转接芯片,…

Java Web学习笔记31——Maven介绍

Maven:Java项目的构建工具。 Maven: Maven是Apache旗下的一个开源项目,是一款用于管理和构建Java项目的工具。 Apache软件基金会,成立于1999年7月,是目前世界上最大的最受欢迎的开源软件基金会,也是一个专…

Java | Leetcode Java题解之第132题分割回文串II

题目&#xff1a; 题解&#xff1a; class Solution {public int minCut(String s) {int n s.length();boolean[][] g new boolean[n][n];for (int i 0; i < n; i) {Arrays.fill(g[i], true);}for (int i n - 1; i > 0; --i) {for (int j i 1; j < n; j) {g[i]…

深度学习中几种常见数据标准化方法

目录 一、介绍 二、总结 三、详情 1. StandardScaler 2. MinMaxScaler 3. RobustScaler 4. MaxAbsScaler 5. Normalizer 6. QuantileTransformer 7. PowerTransformer 8. Log Transform 四、示例 五、心得 一、介绍 方法名称缩放范围适用条件StandardScaler均值…

python 判断点和线段相交

python 判断点和线段相交 import numpy as np import cv2 import numpy as npdef point_to_line_distance(points, line_segments):# line_segments [[549, 303], [580, 303]]# points [565, 304]x0, y0, x1, y1line_segments[0][0], line_segments[0][1], line_segments[1]…

【python】OpenCV GUI——Trackbar(14.2)

学习来自 OpenCV基础&#xff08;12&#xff09;OpenCV GUI中的鼠标和滑动条 文章目录 GUI 滑条介绍cv2.createTrackbar 介绍牛刀小试 GUI 滑条介绍 GUI滑动条是一种直观且快速的调节控件&#xff0c;主要用于改变一个数值或相对值。以下是关于GUI滑动条的详细介绍&#xff1a…

服务器部署spring项目jar包使用bat文件,省略每次输入java -jar了

echo off set pathC:\Program Files\Java\jre1.8.0_191\bin START "YiXiangZhengHe-8516" "%path%/java" -Xdebug -jar -Dspring.profiles.activeprod -Dserver.port8516 YiXiangZhengHe-0.0.1-SNAPSHOT.jar 将set path后面改成jre的bin文件夹 START 后…

knoXSS(case01~10)

case 01: 先在每个框里都输入:<script>alert(1)</script> 检查源码 这里第三个和第四个点都被处理过了&#xff0c;所以先考虑第一个和第二个点 这里试了一下&#xff0c;发现GET也能传参&#xff0c;所以构造 成功 case 02: 这里发现变量a和这个似乎有关联&…

专业学习|南开大学《随机过程》学习笔记(一)

&#xff08;1&#xff09;有哪些经典的关于基本随机过程的书籍推荐&#xff1f; 对于想要系统学习基本随机过程的学生来说&#xff0c;可以参考Sheldon M.Rose编著的经典著作《随机过程》。该书涉及的内容也比较宽泛。但并不局限于单个细节论证。 此外&#xff0c;萨缪尔科林(…

抓住时机的核心:坚持学习准备着

在这个快节奏的时代&#xff0c;时间对于每个人来说都是宝贵的。能否在合适的时间做正确的事情&#xff0c;往往决定了我们成功的概率。但同时&#xff0c;我们也要认识到&#xff0c;逆风翻盘虽少&#xff0c;却并非不可能。在这个过程中&#xff0c;投资自己&#xff0c;投资…

LabVIEW与Python的比较及联合开发

LabVIEW和Python在工业自动化和数据处理领域各具优势&#xff0c;联合开发可以充分发挥两者的优点。本文将从语言特性、开发效率、应用场景等多个角度进行比较&#xff0c;并详细介绍如何实现LabVIEW与Python的联合开发。 语言特性 LabVIEW 图形化编程&#xff1a;LabVIEW使用…

三维地图Cesium,加载一个模型,模型沿着给定的一组经纬度路线移动

目录 实现效果 实现思路 功能点 选择移动路线 加载模型和移动路线 重新运行 指定位置(经纬度点)开始移动 视角切换 到站提示 运行 停止 联动接口 完整代码 html js逻辑 trainOperation.js sourceData.js gitee仓库项目代码 疑问解答 实现效果 三维地图Cesiu…

CopyOnWriteArrayList详解

目录 CopyOnWriteArrayList详解1、CopyOnWriteArrayList简介2、如何理解"写时复制"3、CopyOnWriteArrayList的继承体系4、CopyOnWriteArrayList的构造函数5、CopyOnWriteArrayList的使用示例6、CopyOnWriteArrayList 的 add方法7、CopyOnWriteArrayList弱一致性的体现…

LeetCode790多米诺和托米诺平铺

题目描述 有两种形状的瓷砖&#xff1a;一种是 2 x 1 的多米诺形&#xff0c;另一种是形如 “L” 的托米诺形。两种形状都可以旋转。给定整数 n &#xff0c;返回可以平铺 2 x n 的面板的方法的数量。返回对 109 7 取模 的值。平铺指的是每个正方形都必须有瓷砖覆盖。两个平铺…

先进封装技术的一些优缺点探讨

半导体封装技术是半导体制造过程中的关键环节&#xff0c;它不仅保护了芯片免受物理损伤&#xff0c;还提供了电气连接和散热功能。随着技术的发展&#xff0c;出现了多种先进的封装技术&#xff0c;每种技术都有其特定的应用场景和优缺点。 --> 1. 传统封装技术 【优点】&…

【SpringBoot + Vue 尚庭公寓实战】根据类型查询标签列表接口实现(五)

【SpringBoot Vue 尚庭公寓实战】根据类型查询标签列表接口实现&#xff08;五&#xff09; 文章目录 【SpringBoot Vue 尚庭公寓实战】根据类型查询标签列表接口实现&#xff08;五&#xff09;1、查看接口2、进行开发 1、查看接口 启动项目 访问&#xff1a;http://localho…

macOS优化工具CleanMyMac2024免费版电脑性能提升 存储空间释放 电脑维护 高效易用 延长电脑使用寿命

【CleanMyMac】是一款专为macOS系统设计的优化和清理软件&#xff0c;它的核心特性就是帮助我们提升电脑性能&#xff0c;释放存储空间。&#x1f680; CleanMyMac绿色免费版下载如下&#xff1a;记得保存哈&#xff0c;以防失效&#xff1a; https://pan.quark.cn/s/9b08114…

HTML标签 label for 还是 htmlFor

文章目录 问题结论更多 问题 HTML标签&#xff1a; label 的属性 for 还是 htmlFor&#xff1f; MDN文档&#xff1a;https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label 结论 for 和 htmlFor 都可以使用&#xff0c;都是对的。在部分情况中&#xff0c;只能…

【React】Redux与React - 环境准备

配套工具 在React中使用redux&#xff0c;官方要求安装俩个其他插件 - Redux Toolkit 和 react-redux 配置基础环境 使用 CRA 快速创建 React 项目 npx create-react-app react-redux安装配套工具 npm i reduxjs/toolkit react-redux启动项目 npm run start

计算机网络复习题

期末题库复习1 一. 单选题&#xff08;共32题&#xff0c;100分&#xff09; 1. (单选题) 在脉冲起始时刻&#xff0c;有无跳变来表示“0”和“1”&#xff0c;且在脉冲中间时刻始终发生跳变的编码是&#xff08; &#xff09;。 A.非归零码 B.曼彻斯特编码 C.归零码 D.差…