The Cat Parade

It has been said that trying to keep Hopper focused on a single application is like trying to get cats to walk in a parade (very difficult). The problem is Hopper is designed from its foundation to stress the entire system and never stay in one place too long – its job is to move around. Generally this is a good thing, but if you are trying to isolate a problem or your intent is to stress a particular application (if you are an ISV), it can be frustrating to watch Hopper navigate away from your application and find bugs that are not of interest of you. Hopper does have a built-in option (/a) to help with this, but it can be awkward and sometimes frustrating.

 

I have coded a sample alternative below that simply sits in a tight loop, re-executing the application you want to keep Hopper banging on. The code loops and continually re-launches the application you want to test (this sample focuses on Media Player) and sleeps for a specified period. Using the below, it is possible Hopper will navigate away from your application but once the time duration expires, your application will be switched to front and again receive the brunt of Hopper's fury. I would consider the below bare-bones test code, but it should be sufficient to help you write and customize your own program that does what you need.

 

#include <windows.h>

#define ONE_SECOND 1000

#define TEN_SECONDS (10 * ONE_SECOND)

#define TWENTY_SECONDS (2 * TEN_SECONDS)

#define ONE_MINUTE (3 * TWENTY_SECONDS)

#define FIVE_MINUTES (5 * ONE_MINUTE)

#define FIFTEEN_MINUTES (3 * FIVE_MINUTES)

// Adjust the following to suit your needs

#define SLEEP_TIMEOUT TWENTY_SECONDS

TCHAR *g_pszAppName = TEXT("\\windows\\wmPlayer.exe");

//------------------------------------------------------------------------------

int WINAPI

WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

    LPWSTR lpCmdLine, int iCmdShow)

{

    TCHAR tszTmp[MAX_PATH];

    PROCESS_INFORMATION piProcInfo;

    while(TRUE)

    {

        wsprintf(tszTmp, TEXT(" ... Relaunching: %s"), g_pszAppName);

        OutputDebugString(tszTmp);

        if(! CreateProcess(g_pszAppName, NULL, NULL, NULL, FALSE, 0, NULL,

                NULL, NULL, &piProcInfo))

        {

            goto Error;

        }

        // Adjust this value to suit your needs above

        Sleep(SLEEP_TIMEOUT);

    }

Error:

    // Error condition - should never get here.

    wsprintf(tszTmp, TEXT("ERROR: could not launch %s, last error: %d"),

        g_pszAppName, GetLastError());

    OutputDebugString(tszTmp);

    return(TRUE);

}

 

To use this test application, you will need to copy the above to a .cpp file and add a sources and makefile. Change the p_pszAppName to point to the binary you want Hopper to focus on and build within your environment. Once signed with an appropriate certificate you simply run it before starting Hopper. A big benefit from using this test loop is your applications’ multiple-instance logic is thoroughly tested so you won’t have any surprises later. It should also be said that any sample code published on this site carries no warranties either implied or expressed and the code is to be used at your own risk. Enjoy!