我在DllMain函数里调用SetTimer,然后SetTimer函数调用CALLBACK函数TimerProc,目的想使每5秒中弹出一个提示对话框。最后利用另外一个程序将这个DLL通过CreateRemoteThread函数注入系统的一个进程中。但是注入DLL后(我用工具看到DLL已经注入了一个系统进程中),却没有弹出对话框,请问是怎么回事?是不是我的SetTimer函数没有用对?下面是DLL中的代码:BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{ if (dwReason == DLL_PROCESS_ATTACH)
{
              SetTimer(NULL,0,5000,TimerProc);//DLL被注入一个进程中后,此语句能正常运行吗
} return True;}VOID CALLBACK TimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime )
{
     MessageBox(NULL,"Text","Caption",MB_OK);
}

解决方案 »

  1.   

    Timer需要有一个消息循环来分发
      

  2.   

    你的方法可能不行,你可以采用媒体定时器,下面我给你一个例子:
    UINT CYourTest::TimerScanStart(LPTIMECALLBACK fptc,int TimeCycle,BOOL bTime_OneShot)
    {
    UINT TimeID = 0;
    TIMECAPS tc;
    if(::timeGetDevCaps(&tc,sizeof(TIMECAPS)) == TIMERR_NOERROR)
    {
    DWORD wAccuracy;
    wAccuracy = min(max(tc.wPeriodMin,TIMER_ACCURACY),tc.wPeriodMax);
    if(timeBeginPeriod(wAccuracy) == TIMERR_NOERROR )
    {
    // 参数 TIME_PERIODIC: 周期执行
    if(TimeCycle >= wAccuracy && TimeCycle <= tc.wPeriodMax)
    {
    if(bTime_OneShot)
    {//只执行一次
    TimeID = ::timeSetEvent(TimeCycle,wAccuracy,fptc,(DWORD)this,TIME_ONESHOT);
    }
    else
    {//周期执行
    TimeID = ::timeSetEvent(TimeCycle,wAccuracy,fptc,(DWORD)this,TIME_PERIODIC);
    }
    }
    timeEndPeriod(wAccuracy);
    }
    }
    return TimeID ;
    }void PASCAL CYourTest::OneMilliSecondProc(UINT wTimerID,UINT msg,LPVOID wParam,DWORD dwl,DWORD dw2)
    {
    // do something
    }启动定时器
    m_TimeID = TimerScanStart((LPTIMECALLBACK)OneMilliSecondProc,TIMER_CYCLE_RT,FALSE);
      

  3.   

    如果想利用DLL来做一个监控程序,这样的想法是正确的吗?
    如果不对,请问各位大虾,应该怎样做(基本想法就可以了)。
    是不是最终还是要用SetTimer这个函数,但是这个函数到底应该放在哪个地方呢?是DllMain还是 ………………?
      

  4.   

    MSDN上不是说SetTimer的第一个参数可以为空吗?
    “hWnd 
    Handle to the window to be associated with the timer. This window must be owned by the calling thread. If this parameter is NULL, no window is associated with the timer and the nIDEvent parameter is ignored”
      

  5.   

    我再说一遍Timer需要有一个消息循环来分发
      

  6.   

    那dll中怎么才能有消息循环呢?具体应该怎么做?。谢谢
      

  7.   

    SetTimer之前创建一个窗口,不就有消息循环了?
    SetTimer(hWnd,...);
      

  8.   

    DLL中一般都不创建窗口的,并且我也不需要窗口啊。
    还有没有什么办法呢?能不能用PeekMessage这个函数?
      

  9.   

    SetTimer需要有消息循环支撑,有没有窗体到没关系
    想一下谁把你的Timer消息发给TimerProc
    这部分要自己完成,
    在DllMain里创建一个线程,捕捉消息(GetMessage),然后分发(DispatchMessage)给TimerProc就行了
      

  10.   

    TimerProc是个CALLBACK函数,是由系统调用的,系统负责把WM_TIMER传给它。
    另外好象一般都不能在DllMain中创建一个线程吧!
      

  11.   

    //in dll
    int TimerID = 0;
    void MyTimerProc(HWND hwnd,UINT message,UINT idTimer, DWORD dwTime)   
    {
      
      ::MessageBox(NULL,"timer",NULL,MB_OK);
    }
    void MyFnc()
    {
      MSG msg;
      PeekMessage(&msg,NULL,0,0,PM_NOREMOVE); //强制系统给你产生一个消息队列  
      TimerID = SetTimer(NULL,0,2000,(TIMERPROC)MyTimerProc);
    }看来大家对消息队列还是不很了解,建议去看看windows核心编程一书。to FlyingBaby2006() :另外好象一般都不能在DllMain中创建一个线程吧???!
    为什么不能呢?不要在DllMain中作初始化的工作,因为你不能保证你的dll会被加载几次。除非你有意一定要这样作。
      

  12.   

    我在DllMain中加入了如下代码:
                   if(dwReason == DLL_PROCESS_ATTACH){
    ::SetTimer(NULL,0,10000,TimerProc);
    MSG msg;
    while(::GetMessage(&msg,NULL,0,0))
    {
    ::TranslateMessage(&msg);
    ::DispatchMessage(&msg);
    }
                   }
    现在的SetTimer函数运行正确了,但是当该DLL被注入一个进程后,虽然会每隔10秒弹出一个对话框,但是操作系统上的其它程序就没有反应了。请问应该怎么解决这个问题?
      

  13.   

    if(dwReason == DLL_PROCESS_ATTACH){
    ::SetTimer(NULL,0,10000,TimerProc);
    MSG msg;
    while(::GetMessage(&msg,NULL,0,0))
    {
    ::TranslateMessage(&msg);
    ::DispatchMessage(&msg);
    }
    }while(::GetMessage(&msg,NULL,0,0))
    {
    ::TranslateMessage(&msg);
    ::DispatchMessage(&msg);
    }这里要放出来不然的话,你与进程一attach的时候,就不停的去捕获消息,
    你应该去设置下退出的消息
    也就是GetMessage为0的时候,就如API方式写一个窗口时,当WM_CLOSE消息发送来时,GetMessage为0,退出消息循环不晓得想法对不,
    我也是菜鸟一个
      

  14.   

    while(::GetMessage(&msg,NULL,0,0))
    {
    ::TranslateMessage(&msg);
    ::DispatchMessage(&msg);
    }
    问楼主,这样写你的机子不会高??(我是指CPU占用率),DLL一被ATTATCH,就不停地GETMESSAGE
    “但是操作系统上的其它程序就没有反应了”,你打开任务管理器看看
    建议如果非用TIMER地话,弄个线程,把
    ::SetTimer(NULL,0,10000,TimerProc);
    MSG msg;
    while(::GetMessage(&msg,NULL,0,0))
    {
    ::TranslateMessage(&msg);
    ::DispatchMessage(&msg);
    }
    都放进去
    最好用jason_wentzel() 的办法
      

  15.   

    CPU的占用率不高,但是被注入DLL的那个进程有问题了(并没有被系统强行关闭),只是好象没有反应了!
      

  16.   

    当然没反应了,一直卡在DllMain中,怎么会有反应。
      

  17.   

    明白了,你是把它注入到另一个进程中了,是吧,那CPU 就没问题了,但原因还是那
    当用CREATEREMOTETHREATE 以LOADLIBRARY作为线程函数在远程进程中开一线程,线程是开了,也在远程进程中加载DLL了,但是LOADLIBRARY 会在某个阶段调用DLLMAIN,因为有while(::GetMessage(&msg,NULL,0,0))
    {
    ::TranslateMessage(&msg);
    ::DispatchMessage(&msg);
    }
    DLLMAIN没法返回,所以会一直没反映。(我觉得整个系统都会有问题,并不想你说得只是注入进程有问题)
    解决方法就是在DLL的PROCESSATTACH时启动一进程,在进程中完成一些事情,难道你费半天劲注入的DLL,只想让它在初始化时做点事情,然后其他时间什么都不干??
    但要注意最好用CREATETHREAD创建线程
    你所说的不能在DLLMAIN中开启线程,是不能在THREADATTACH时调用开启线程的函数
      

  18.   

    问题已经解决了,在DllMain中创建一个线程(我原来其实并不想这么做的)就可以了!
    谢谢大家的支持!准备散分了…………   ^-^