【C++实现com组件每天单次检查更新(Win32 Atom表)】

C++实现com组件每天单次检查更新(Win32 Atom表)

使用场景:window下com组件(ocx/atldll)会被多个应用程序调用,但是只能确保每天只会执行一次检查更新
实现思路:
1.因为com组件涉及多进程调用,所以会有多个进程都需要检查是否当天已经执行更新,所以选择com组件的入口函数中执行,确保系统中不管哪个进程调用哪个方法都会检查更新逻辑
2.实现单次更新可以使用配置文件来控制,但是多次读取配置文件操作必然会影响性能,所以我选择Windows系统的Atom来实现,并且是在系统中作唯一标识,所以使用全局原子
3.原理就是当第一个进程在调用com的时候会先使用全局Atom进行标记,其他进程在调用之后会检查系统中是否存在这个标记,如果存在该标记就不执行更新逻辑,否则就执行
代码实现:

  • 在com返回类工厂的函数中添加Atom标记逻辑
std::string GetCurrentDateString() {
    // 获取当前时间 注意只能到d
    std::time_t t = std::time(nullptr);
    std::tm now;
    localtime_s(&now, &t);
    char buffer[11]; 
    std::strftime(buffer, sizeof(buffer), "%Y-%m-%d", &now);
    return std::string(buffer);
}

STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ LPVOID* ppv)
{
    std::string dateString = GetCurrentDateString();
     ATOM existingAtom = GlobalFindAtomA(dateString.c_str());
    // 添加全局原子
     GlobalFindAtom(lpString);
// existrigAtom 为0时就是不存在
    if (existingAtom  == 0) {
        ATOM atom = GlobalAddAtomA(lpString);
        std::cout <<  << "标记添加成功"<< std::endl;
        // UpdateTest()
        // 代表第一次添加Atom标识,所以执行一次检查更新逻辑
    } else {
        std::cerr << "已经存在标记" << std::endl;
    }
	return _AtlModule.DllGetClassObject(rclsid, riid, ppv);
}
  • 更新逻辑的实现
  • 一般软件的更新都会停机更新,因为文件占用的时候更新会导致数据丢失或异常 ,但是本次实现com组件的不停机更新,原理是通过修改ocx或者atldll的名字来实现。利用的是文件在占用的时候可以修改名字的特点来实现
  • 具体就是在com组件被加载时,给需要替换的文件添加一个新的后缀,再把新的文件(名字需要保持和原来注册的com组件一致)复制到当前目录,这样当进程第二次加载时就是加载的新的com组件,并且不会影响当前正在使用的com组件,因为Windows每个进程都会拷贝一份注册的com组件在各自的进程中运行

更新逻辑实现:

   void UpdateTest(){
   // 比如之前com名字是 test1.ocx
   // 使用rename更改文件名
   int  ret = rename("test1.ocx","test1.ocx.old");  //此时更改名字不会影响已经加载的正常进程
   if(ret!=0){
       // 失败
       return ;
   }
   // 如果成功就将新的com组件移动到com组件的注册路径
   // D:/old/test1.ocx 是新的文件路径
 if (rename("D:/old/test1.ocx", "C:/pag/test1.ocx") == 0) {
    // 更新成功
    //也可以选择删除 test1.ocx.old
 }
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值