installscript

InstallScript detect app during upgrade?


MyApp.exe is installed using an InstallScript 2014 project. The folks in manufacturing recently tried to upgrade to a more recent development version but did not close the existing instance of MyApp. This resulted in many permission denied errors since the various dll's used by the app were locked and in use.

I expected the InstallScript executable to do the usual "stage and reboot" thing that all Windows folks are intimate with. It did not do that, and I can't see anything in the InstallShield project editor that obviously lets me force that behavior.

I also expected InstallScript to allow me to somehow detect that my app was already running - if I can do that, I can display a dialog to give the user a chance to close the app and continue. The only solution for this is InstallSite.org List and Shutdown Running Processes. (Note this is unanswered on another S/O question.)

That does not properly detect all of the running tasks, including my own.

Before I spend a couple of days trying to fix what seems to be an obviously missing feature of InstallScript, I thought I'd ask if there's a better approach.


Solution

  • Here's what I came up with. Hope this helps.

    // defines/protos for finding a process
    #define TH32CS_SNAPPROCESS  0x00000002
    
    // in Kernel32.dll
    prototype NUMBER    Kernel32.CreateToolhelp32Snapshot(NUMBER , NUMBER);
    prototype BOOL      Kernel32.Process32First(HWND , POINTER );
    prototype BOOL      Kernel32.Process32Next(HWND , POINTER );
    
    // from minwindef.h, windows api
    typedef PROCESSENTRY32
    begin
        number dwSize;
        number cntUsage;
        number th32ProcessID;          // this process
        number th32DefaultHeapID;
        number th32ModuleID;           // associated exe
        number cntThreads;
        number th32ParentProcessID;    // this process's parent process
        number pcPriClassBase;        // Base priority of process's threads
        number dwFlags;
        STRING szExeFile[MAX_PATH];     // Path
    end;
    
    // ========================================================================================
    // list all of the running processes, see if Flex is running
    // based on https://msdn.microsoft.com/en-us/library/windows/desktop/ms686701(v=vs.85).aspx
    // ========================================================================================
    function BOOL IsProcessRunning(sProcessName)
        HWND hProcessSnap;
        PROCESSENTRY32 pe;
        POINTER ppe;
        NUMBER ret;
    
    begin
        hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    
        pe.dwSize = SizeOf(pe); 
        ppe = &pe;
    
        ret = Process32First(hProcessSnap, ppe);
    
        if (ret == 0) then
          //printError(TEXT("Process32First")); // show cause of failure
          CloseHandle(hProcessSnap);          // clean the snapshot object
          return(FALSE);
        endif;
    
        repeat      
            if (StrCompare(sProcessName, pe.szExeFile) == 0) then
                CloseHandle(hProcessSnap);          // clean the snapshot object
                return(TRUE);
            endif;
            ret = Process32Next(hProcessSnap, ppe);
        until (ret == 0);
    
       return(FALSE);
    end;
    

    You then call it

    if (IsProcessRunning("WORD.EXE")) then
        blah blah
    endif;