locked
EnumWindows call takes long time to execute after power on RRS feed

  • Question

  • Hi,

    I have another query related to EnumWindows call. I am using the code written below;


    #include "Windows.h"

    /* ENUM WINDOWS */
    static BOOL CALLBACK EnumWinProc(HWND hWnd, LPARAM pContext)
    {
    if(!IsWindowVisible(hWnd))
    {
    return TRUE;
    }

    TCHAR szWindowText[MAX_PATH];
    memset(szWindowText,0,sizeof(TCHAR)*MAX_PATH);

    GetWindowText(hWnd, szWindowText, MAX_PATH);
    if ('\0' == *szWindowText)
    {
    return TRUE;
    }

    TCHAR szClassName[MAX_PATH];
    memset(szClassName,0,sizeof(TCHAR)*MAX_PATH);

    GetClassName(hWnd,szClassName,MAX_PATH);
    if (!_tcscmp(szClassName,TEXT("MS_SIPBUTTON")))
    {
    return TRUE;
    }

    HANDLE hProc = NULL;
    WCHAR wszBuf[MAX_PATH];
    DWORD dwProcessId = 0;

    GetWindowThreadProcessId(hWnd, &dwProcessId);

    hProc = OpenProcess(PROCESS_ALL_ACCESS,0,dwProcessId);
    memset(wszBuf,0,sizeof(WCHAR)*MAX_PATH);

    GetModuleFileName((HINSTANCE)hProc, wszBuf, MAX_PATH);
    CloseHandle(hProc);

    /* Some more code here */

    return TRUE;
    }

    /* MAIN */
    int _tmain()
    {
    DWORD dwStartTime = GetTickCount();
    EnumWindows(EnumWinProc,0);
    int iTotalTime = GetTickCount() - dwStartTime;

    TCHAR tcNumber[100];
    memset(tcNumber,0,sizeof(TCHAR)*100);
    _itow(iTotalTime,tcNumber,10);

    MessageBox(NULL,tcNumber,TEXT("Time taken:"),MB_OK);
    return 0;
    }

    If I execute this application as soon as my device, not emulator, starts up that is I can see the today screen, I launch this application immediately. It takes somewhere around 12-14 seconds, but if I launch the same application after say like 30 seconds after the device boots up, it takes around 3-7 ms to execute.

    Why is such a huge time difference is what I cannot understand. I am using Visual Studio 2005 and working on device and not emulator for this application.

    Thank you,
    CED


    Thursday, October 8, 2009 9:19 AM

All replies

  • Perhaps the system is still performing some maintenance work in the background related with the system startup, thus taking your CPU time. You may try prioritizing your process to real-time to check this.

    Also, it is possible that one of the APIs that you call from your callback function uses some data that is cached at the first call. Thus any future calls are faster. You may test the code in parts by calling each API one after another to see which one has the biggest delay difference.
    Thursday, October 8, 2009 11:51 AM
  • Hi ranosoft,

    As per you comment I had put logs in my code to see on enumaration of which process it is taking most of the time. I found that when it takes most of the time, the logs is such that, after it enumarates itself, it takes lots of time, nearly 14 seconds after which it enumarates the next process.

    But, another interesting fact is that, if I run the application again and it takes 3 ms, during enumaration, it does not enumarate itself. The thing which I can conclude from the logs are that when in enumaration it finds itself, it takes the max amount of time and it happens only once and that too if I execute it imediately after power on but not if I wait for say some 30 seconds and then launch it.

    Any ideas ?

    Thank you,
    CED
    Thursday, October 8, 2009 1:55 PM
  • What do you mean by "enumerate itself"? Do you have any windows in your application and you refer to one of them as "itself"?

    As a side note, you may safely replace statements like this:

    memset(szClassName,0,sizeof(TCHAR)*MAX_PATH);

    with this:

    *szClassName= '\0';

    as long as you treat szClassName as a NULL-terminated string. In your code there are 2 such cases.
    Thursday, October 8, 2009 2:11 PM
  • Enumerate itself I mean, GetModuleFilename returns the path of this application that is, \Windows\SampleEnum.exe, but it comes in log only once that is when the call takes maximum amount of time.

    To be more clear, in the log, when EnumWindows takes maximum amount of time, there is a log which has \Windows\SampleEnum.exe as the out of GetModuleFileName but if I run it again and it takes 3 ms to run this log is not present.

    Thank you for your opinion about the memset, I will change it as it is a NULL terminated string.

    Thank you,
    CED
    Thursday, October 8, 2009 2:18 PM
  • OK, but do you really have any windows in your app? (that is: do you call CreateWindow, DialogBox, or a similar API to create a window that remains present while you call your enumeration?)

    In your place, I would measure the speed of this code after removing the call to GetModuleFileName. Then also after removing OpenProcess, then GetWindowThreadProcessId, and so on. This could give you a thought about the nature of the problem.

    Also, try to put your app in a different folder than \Windows\. Enumerating this folder alone can take some time.
    Thursday, October 8, 2009 2:36 PM
  • No, I am not creating any window neither I have any hidden window. I have posted the entire source code. The API calls inside EnumWindow is not making the delay cause from log I saw that the delay happens between enumaration of two processes and not by any of the Win32 API calls inside EnumWindow.

    About placing it in Windows folder, I placed it inside the temp folder, but the situation remains the same.

    Thank you,
    CED
    Friday, October 9, 2009 5:36 AM
  • Hi,

    Regarding this topic I have only query. If a non-window, console application is running in while(1) that is after _tmain() inside the body there is only while(1). Now if another application is calling EnumWindows call, will the call get stuck while it enumerates the non-window console application.

    Thank you,
    CED
    Thursday, November 12, 2009 5:34 AM