项目场景:
最近开发一个项目,安装环境是 D://AA//BB,AA 是公共库文件夹,BB 是子模块文件夹,AA 和 BB 文件夹的绝对路径都保存在环境变量中,BB 子模块文件夹中有一个服务程序,程序启动后也需要启动该服务程序;因为是市场上反馈了有问题,需要售后同事配合测试,结果悲剧了
问题描述:
问题很块就处理,本地测试验证通过后,就邮件发给现场同事进行验证,同时邮件备注了每个库分别拷贝存放的路径,但是就是不行,我就问售后,文件是否拷贝对了,他们说拷贝好了;
无奈,只能新增日志,发给售后重新验证,并查看发回来的日志;结果一看,新增的日志一个都没记录,一看就是没替换之前的库,售后检查一下,果然是,唉!
说到这,还没完,替换后,发现还有个小问题要处理,改了后邮件发给售后,拷贝路径同时贴好,但就是不生效,同时跟售后拍照确认了库已经替换,本地也验证OK,现场就是不行,百思不得其解;
继续测试,并且和现场测试数据保持一致,本地测试一切正常,实在没办法,继续加日志给现场设置,后来发现,是 BB 子模块文件夹中那个服务程序的问题。
原因分析:
程序启动后,会调用WinExec启动 BB 子模块文件夹中那个服务程序,然后进行进程间通讯,但是由于安装路径不固定,并且配置了环境变量,为了省事😅,所以直接传参文件名了,并且一直使用没出过问题;
售后同事第一次拷贝错了,将服务程序拷贝到 AA 文件夹下,AA 路径也都保存在环境变量中,即使后边每次拷贝替换 BB 路径下面的服务程序,程序启动直接运行AA 路径下的老服务程序了,所以修改不生效,小小的问题折腾了大半天😓;
程序开发还是不要怕麻烦的好,指不定哪天出现奇葩的问题
解决方案:
安装路径不固定,可先使用 GetModuleHandle 获取当前模块句柄(我这边是 dll 里面启动服务,所以需要调用该函数获取 dll 模块句柄,dll 和 服务程序在相同路径下面),然后使用 GetModuleFileName 函数获取当前进程所在绝对路径,之后重新组装要启动的子进程所在路径,相关函数原型如下:
// 执行成功,则返回模块句柄;表示失败
HMODULE WINAPI GetModuleHandle(
_In_opt_LPCTSTR lpModuleName // 指定模块名,这通常是与模块的文件名相同的一个名字,我这边用的是 dll 库名,NULL则返回调用进程本身的句柄
);
// 执行成功,返回复制到lpFileName的实际字符数量;零表示失败
DWORD WINAPI GetModuleFileName(
_In_opt_ HMODULE hModule, // 一个模块的句柄。可以是一个DLL模块,或者是一个应用程序的实例句柄。如果该参数为NULL,
该函数返回该应用程序全路径。
_Out_ LPTSTR lpFilename, // 指定一个字串缓冲区,要在其中容纳文件的用NULL字符中止的路径名,hModule模块就是从这个文件装载进来的
_In_ DWORD nSize // 装载到缓冲区lpFileName的最大字符数量
);