MAKEMSI quickly and reliably creates MSI files in a non-programmatic way
Have your say! Join the MAKEMSI discussion list or view archive! Suggest improvements. No question too simple or too complex.
[Bottom][Contents][Prev]: PROCESS MONITOR[Next]: PV.EXE
Have your say! Join the MAKEMSI discussion list or view archive! Suggest improvements. No question too simple or too complex.
\->Tips and Tricks->Tools->PsSuspend.EXE

PsSuspend.EXE

This tool can suspend or resume tasks by name of process ID (PID). You will probably be interested in this tool as it can improve MAKEMSI's performance in some situations.

This is one of a large number of excellent free tools available from SysInternals.

Note that this command doesn't handle masks so the example below first uses "PV.EXE" to convert a list of masks into a list of running processes.

PsSuspend.EXE /?


PsSuspend v1.05 - local and remote process suspender/resumer
Copyright (C) 2001-2003 Mark Russinovich
Sysinternals - www.sysinternals.com

PsSuspend suspends or resumes processes on a local or remote NT system.

Usage: pssuspend [-r] [\\RemoteComputer [-u Username [-p Password]]] <process Id or name>
     -r    Resume.
     -u    Specifies optional user name for login to
           remote computer.
     -p    Specifies optional password for user name. If you omit this
           you will be prompted to enter a hidden password.

EXAMPLE: SUSPEND PROCESSES WHILE MAKEMSI EXECUTES

I run a number of CPU intensive background tasks (for example "seti@home") these generally run at "idle" priority. Windows still allows it to consume extensive CPU resources otherwise required by tasks with much higher priorities!

I still wish to run "seti@home" so the following code is my solution to the problem which allows MAKEMSI to run about 30% faster (its near the start of my "DENNIS.MMH" header file):

;----------------------------------------------------------------------------
;--- Define list of resource intensive background applications --------------
;----------------------------------------------------------------------------
#( ';'
    #define @@SuspendProcessList
    seti@home.exe                      ;;Little Green Men...
    *_windows_intelx86*                ;;BOINC - All BOINC processes have this naming convention? (not all have ".exe" extension!)
    WCGrid_Rosetta.exe                 ;;Cancer Research etc
    GIANTAntiSpywareMain.exe           ;;Microsoft AniSpyware
    CopernicDesktopSearch.exe          ;;Can interfere with builds
    ud_ligfit_Release.exe              ;;United Devices

    ;--- Not suspending (as this stops explorer etc working while building msi) ---
    ;YahooDesktopSearch.exe             ;;Can interfere with builds (suspending can stop Explorer etc opening)
                                        ;;Commented out if it still hangs until the piece of cr.p
#)


;----------------------------------------------------------------------------
;--- Stop CPU intensive processes as soon as possible -----------------------
;----------------------------------------------------------------------------
;---[4Doco-HookIntoExample]---
#(
    ;--- Code we wish to execute early in build (but after logging locations known) ---
    #define SuspendCpuIntensiveTasks

    ;--- Need to perform latter when the logging directory is known! --------
    #evaluate ^^ ^<$Rexx4SuspendCpuIntensiveTasks>^
#)
#include "HookInto.MMH"             ;;We haven't already included the MAKEMSI headers...
<$HookInto "MAKEMSI_HOOK_ASAP_AFTER_LOG_DIRECTORIES_DEFINED" Before="SuspendCpuIntensiveTasks">
;---[4Doco-HookIntoExample]---
#DefineRexx 'Rexx4SuspendCpuIntensiveTasks'
    ;--- Create logging directory -------------------------------------------
    @@MainDir = '<$MAKEMSI_OTHER_DIR>\SuspendResume'
    @@LogDir = @@MainDir || '\Logs'
    call AddressCmd 'rd "' || @@LogDir  || '" /q /s >nul <$Stderr2Out>'
    call AddressCmd 'rd "' || @@MainDir || '" /q /s >nul <$Stderr2Out>'
    call MakeDirectoryTree @@LogDir;

    ;--- Set up files -------------------------------------------------------
    @@ProcessFile = @@MainDir || '\MatchingProcesses.txt';
    @@SuspendCmd  = @@MainDir || '\Suspend.CMD';     ;;Only for user invokation (if user aborted - may need to be manually executed)
    @@ResumeCmd   = @@MainDir || '\Resume.CMD';      ;;Only for user invokation (if user aborted - may need to be manually executed)
    call FileDelete @@ProcessFile;
    call FileDelete @@SuspendCmd;
    call FileDelete @@ResumeCmd;

    ;--- Initialize "emergency" Batch file (user invoked if required) -------
    @@Batch = "@echo off" || '0A0A'x;
    @@Batch = @@Batch || '@REM ***' || '0A'x;
    @@Batch = @@Batch || '@REM *** Provided for your use (not actually used by MAKEMSI due to AntiSpyware programs)' || '0A'x;
    @@Batch = @@Batch || '@REM ***' || '0A0A'x;
    @@Batch = @@Batch || '@REM *** List of MASKS ***' || '0A'x;

    ;--- Produce a file containing the matching tasks (those running any matching the mask) ---
    call ArraySplit '@@ProcessMasks', '<$@@SuspendProcessList>', ';'
    @@PvExe = "PV.EXE --quiet"
    do  @@i = 1 to @@ProcessMasks.0
        ;--- Add this wilcard process mask to the list ----------------------
        @@PvExe = @@PvExe || ' "' || @@ProcessMasks.@@i || '"';
        @@Batch = @@Batch || "@REM MASK #" || @@i || ': ' || @@ProcessMasks.@@i || '0A'x;
    end
    @@Batch = @@Batch || '0A0A'x;

    ;--- Process matching (running) processes -------------------------------
    address system @@PvExe || ' > "' || @@ProcessFile || '" 2>&1'
    @@ProcessCnt = 0;
    do  while lines(@@ProcessFile) <> 0
        ;--- All lines should have a tab (process name ends with tab) -------
        @@Line   = linein(@@ProcessFile);
        @@TabPos = pos('09'x, @@Line);

        ;--- Now Extract the Name of the process ----------------------------
        if  @@TabPos <> 0 then
        do
            ;--- Looks OK ---------------------------------------------------
            @@ProcessCnt  = @@ProcessCnt + 1;
            @@ProcessName = left(@@Line, @@TabPos-1);

            ;--- Create Batch file resume command ----------------------------
            @@Batch = @@Batch || 'PsSuspend.exe {Action} "' || @@ProcessName || '"' || '0A'x;

            ;--- Add to the Process list ------------------------------------
            @@Process.@@ProcessCnt = @@ProcessName;
        end;
    end;
    call FileClose @@ProcessFile;
    @@Process.0 = @@ProcessCnt;

    ;--- Actually create the batch files ------------------------------------
    @@Batch = ReplaceString(@@Batch, '0A'x, '0D0A'x);
    call FileLineOut @@SuspendCmd, ReplaceString(@@Batch, "{Action} ", "");
    call FileLineOut @@ResumeCmd,  ReplaceString(@@Batch, "{Action}",  "-r");
    call FileClose @@SuspendCmd;
    call FileClose @@ResumeCmd;     ;;We won't actually run the batch files automatically due to SpyWare programs etc...

    ;--- Schedule RESUME at end of PPWIZARD's processing --------------------
    call ScheduleCleanupCode 'ResumeCpuIntensiveTasks';

    ;--- SUSPEND ignoring return codes/failure (but log for debug) ----------
    do  @@i = 1 to @@Process.0
        @@LogFile = @@LogDir || '\Suspending-' || @@Process.@@i || '.log'
        address system 'PsSuspend.EXE "' || @@Process.@@i || '" > "' || @@LogFile || '" 2>&1'
    end
#DefineRexx


;----------------------------------------------------------------------------
;--- This RESUME code was scheduled in the SUSPEND step above ---------------
;----------------------------------------------------------------------------
#DefineRexx 'ResumeCpuIntensiveTasks'       ;;Define "resume" code (not yet executed)
    ;--- RESUME ignoring return codes/failure (but log for debug) -----------
    do  @@i = 1 to @@Process.0
        @@LogFile = @@LogDir || '\Resuming-' || @@Process.@@i || '.log'
        address system 'PsSuspend.EXE -r "' || @@Process.@@i || '" > "' || @@LogFile || '" 2>&1'
    end
#DefineRexx

Note that the above is not perfect as it doesn't take into account that I could be running more than one MAKEMSI process at a time. I could tweek the code to handle this but don't consider it worth the added complication.

A possibly better way particularly if you are setting up the configuration for a larger company is to make it (possibly optionally) execute a batch file pointed to by an environment variable (or perhaps located in the MAKEMSI directory), passing it "START" and "STOP" parameters. This allows each team member to have a personalised configuration.


Microsoft awarded me an MVP (Most Valuable Professional award) in 2004, 2005, 2006, 2007, 2008 & 2009 for the Windows SDK (Windows Installer) area.Please email me any feedback, additional information or corrections.
See this page online (look for updates)

[Top][Contents][Prev]: PROCESS MONITOR[Next]: PV.EXE


MAKEMSI© is (C)opyright Dennis Bareis 2003-2008 (All rights reserved).
Sunday August 13 2017 at 2:39pm
Visit MAKEMSI's Home Page
Microsoft awarded me an MVP (Most Valuable Professional award) in 2004, 2005, 2006, 2007, 2008 & 2009 for the Windows SDK (Windows Installer) area.