xe10.1在dll创建的createTimerQueue,忘记删除了,怎么破?

aidpoint20126 2024-06-26 11:41:02

江湖救急,江湖救急,江湖救急

在多线程中调用了一个dll编写的插件,创建了一个定时器createTimerQueueTimer,结果忘记删除了,导致改定时器 一直在执行,

现在想把这个定时器删除了,不知道咋个搞?麻烦高手解决一下 ,红包 奉上

...全文
成就一亿技术人!
拼手气红包 50.00元
313 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复

能回这样帖子的都是高手啊。
我是来凑数的,我不明白的是,DLL重搞一下不行吗?

  • 举报
回复
@秋天之落叶 可以重搞啊,但是前面已经创建的了定时器怎么删除啊?
@aidpoint20126 GetModuleHandle、FreeLibrary
  • 打赏
  • 举报
回复

不知道创建的定时器队列的句柄?那就是没有源码,你要搞别人的DLL,关闭定时检查什么什么事件之类的?估计你的水平还稍微欠一点点。
没有句柄怎搞呢,简单说就是:
调用NtQuerySystemInformation,查询类型SystemHandleInformation
对返回的缓冲区的每个handle
调用NtQueryObject,查询的对象信息类ObjectTypeInformation
返回结构中有它的类型名字符串
然后你判断是否需要CloseHandle即可~~~

  • 举报
回复
@日立奔腾浪潮微软松下联想 我自己的源码,自己写的dll,最开始是创建了定时器队列和定时器,然后把dll运行了一段时间,后来发现没有删除定时器,就在代码里面加上了删除代码,结果前面创建的定时器由于没有删除 代码,所以没有删除,现在我想把他删除了,是这么个意思
  • 打赏
  • 举报
回复

兄弟,能给个删除的代码吗?dll我自己可以搞定

  • 打赏
  • 举报
回复

如果你在使用 Embarcadero RAD Studio XE10.1 中创建了一个名为 createTimerQueue 的 DLL 函数,但忘记了删除它,可以通过以下步骤进行处理:

编写一个修复DLL函数的程序:创建一个新的 DLL,其中包含一个函数,用于删除或清理之前创建的 createTimerQueue。这种方法通常需要对你的原始 DLL 的代码和功能有较深的理解。你需要确保新的 DLL 可以正确识别和处理 createTimerQueue 的创建,并执行适当的清理操作。

或者创建一个新的DLL.

  • 举报
回复
@recin_com_cn //旧dll 创建定时器代码 ... var timerHandle,timerQueue:Thandle; begin timerQueue:=createTimerQueue; if timerQueue<>0 then if not createTimerQueueTimer(timerHandle,timerQueue,@TimerCallback,nil,interValNum,0,0) then log('创建失败'); end; //新的dll怎么删除旧dll中 创建的定时器啊?用下面的删除代码没有定时器句柄啊 deleteTimerQueueTimer(timerQueue,timerHandle,invalid_handle_value); deleteTimerQueue(timerQueue);
  • 打赏
  • 举报
回复 1

在Windows中,如果你创建了一个定时器(TimerQueueTimer),但是忘记删除它,定时器会一直执行。要删除这个定时器,可以使用DeleteTimerQueueTimer函数。下面是如何删除定时器的步骤:

  1. 创建定时器
    当你创建定时器时,通常会保存定时器的句柄,以便以后删除它。

#include <windows.h>

// 定时器句柄
HANDLE hTimer = NULL;

// 定时器回调函数
void CALLBACK TimerRoutine(PVOID lpParam, BOOLEAN TimerOrWaitFired)
{
// 定时器任务
}

void CreateMyTimer()
{
CreateTimerQueueTimer(
&hTimer, // 定时器句柄
NULL, // 默认的定时器队列
TimerRoutine, // 定时器回调函数
NULL, // 传递给回调函数的参数
0, // 定时器首次触发的延迟时间(毫秒)
1000, // 定时器间隔时间(毫秒)
0 // 定时器选项
);
}
2. 删除定时器
要删除定时器,可以使用DeleteTimerQueueTimer函数。需要注意的是,DeleteTimerQueueTimer会等待所有正在运行的回调函数执行完毕,然后再删除定时器。

void DeleteMyTimer()
{
if (hTimer != NULL)
{
// 删除定时器
if (!DeleteTimerQueueTimer(NULL, hTimer, INVALID_HANDLE_VALUE))
{
// 删除失败
printf("DeleteTimerQueueTimer failed with error %d\n", GetLastError());
}
else
{
// 成功删除定时器
printf("Timer successfully deleted\n");
}
hTimer = NULL;
}
}
3. 在多线程环境中删除定时器
在多线程环境中,需要确保在删除定时器时不会与其他线程发生竞争。可以使用互斥锁(Mutex)或临界区(Critical Section)来保护定时器的创建和删除操作。

#include <windows.h>
#include <stdio.h>

HANDLE hTimer = NULL;
CRITICAL_SECTION cs;

void CALLBACK TimerRoutine(PVOID lpParam, BOOLEAN TimerOrWaitFired)
{
// 定时器任务
}

void CreateMyTimer()
{
EnterCriticalSection(&cs);

CreateTimerQueueTimer(
    &hTimer,                   // 定时器句柄
    NULL,                      // 默认的定时器队列
    TimerRoutine,              // 定时器回调函数
    NULL,                      // 传递给回调函数的参数
    0,                         // 定时器首次触发的延迟时间(毫秒)
    1000,                      // 定时器间隔时间(毫秒)
    0                          // 定时器选项
);

LeaveCriticalSection(&cs);

}

void DeleteMyTimer()
{
EnterCriticalSection(&cs);

if (hTimer != NULL)
{
    // 删除定时器
    if (!DeleteTimerQueueTimer(NULL, hTimer, INVALID_HANDLE_VALUE))
    {
        // 删除失败
        printf("DeleteTimerQueueTimer failed with error %d\n", GetLastError());
    }
    else
    {
        // 成功删除定时器
        printf("Timer successfully deleted\n");
    }
    hTimer = NULL;
}

LeaveCriticalSection(&cs);

}

int main()
{
InitializeCriticalSection(&cs);

CreateMyTimer();

// 模拟一些操作
Sleep(5000);

DeleteMyTimer();

DeleteCriticalSection(&cs);
return 0;

}
在这个例子中,使用了临界区来保护对定时器句柄的访问,确保在多线程环境中安全地创建和删除定时器。你可以根据你的实际情况选择合适的同步机制,如互斥锁或事件。

  • 举报
回复
@清风明月9987321 多谢支援,但是现在的 问题是,我不知道创建的定时器的句柄了,有没有什么 办法把他找出来
  • 举报
回复
@清风明月9987321 就是我原来创建的定时器的句柄我不知道了,怎么删除呢?
tanqth 06-27
  • 打赏
  • 举报
回复 1

既然是“忘记删除了”,那就把删除加上吧。

  • 打赏
  • 举报
回复

我很同意,话说发15个字的评论能获得积分,我也试一试

  • 打赏
  • 举报
回复
定位定时器: 首先,检查代码中是否有一个全局变量或类成员保存了对定时器的引用,这可能是Windows::Threading::TimerQueueTimer或类似对象。

获取句柄或ID: 找到定时器后,你可能需要它的句柄(如果库提供了这样的接口)或者它的ID来停止它。这通常可以通过定时器对象的成员函数获取。

取消定时器: 使用获得的句柄或ID,调用cancel()、stop()或类似的方法来停止定时器。这取决于库的具体实现,例如在Windows API中可能是CloseHandle(timerHandle),而在WinRT中可能是timer.Cancel()。

清理资源: 如果定时器对象是动态分配的,记得将其从内存中释放,以防止内存泄漏。

处理异常: 在尝试取消定时器时,确保捕获任何可能出现的异常,如找不到句柄或无效操作。

日志和调试: 为了解决这类问题,记录相关的日志信息以便于追踪和解决问题。

如果你在DLL中无法直接操作,可能需要通过插件提供的API或者通知机制来请求父进程或管理器停止定时器。

5,555

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧