cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
ZygoCorp
Level 6

how do I check if my application is running

yes, this is essentially the same topic as the thread "Another bug: Is( FILE_LOCKED, szFilename ) always returns TRUE on Win Vista and Win 7" but I'm going to ask again, more plainly and hope that someone has a more plain answer.

#1 - this is an InstallScript project running on windows 7

BEFORE my installer gets into performing an update, remove, or repair, I need to make sure our exe is NOT running. I would like a check is as early in the process as possible, like in OnSetupMode() - something like the version checks. If things are not kosher with the version number comparisions here, the setup exits. I'm looking for something similiar to find out if an exe we install is running.

It was recommended to use OnFileLocked() by someone for the other thread. However, (1) I could not figure how to use this event because the documentation was not good and (2) the event doesn't occur until the file name provided is attempted to be installed. I have no idea when in the install process that is because we have 20 components and up to 20 files in each component. I also don't think it is a good idea to let the user get that far into the update/remove process only to then notice that program is running and stop the update/remove. If the program is running I would expect that the very first message form the installer would be "can't proceed until you stop the application"

I just need to know if one exe that is among the many we install is running. If it is, stop the install right away. I did look at the example for installshield 6 in "List and Shut Down Running Applications" also recommened in the thread mentioned above and didn't really follow it.

thanks much. I can't believe this is that hard a thing to accomplish.:confused:
Labels (1)
0 Kudos
(17) Replies
Christopher_Pai
Level 16

Two approaches that I know

1) Use WMI to query win32_process and look to see if your process is there:

2) Have your program create a mutex when it starts up and dispose it when it shuts down. In your installer check to see if that mutex exists.
0 Kudos
ZygoCorp
Level 6

we are running a 64bit application on windows 7 64 bit. will the wmi thing work?
0 Kudos
rguggisberg
Level 13

If you are comfortable working with Windows Shell Scripts you can do something like this in a bat file:

@ECHO OFF
REM Next 5 lines only needed if you need to support Win2K or older.
TASKLIST /? > nul 2> nul
IF ERRORLEVEL 1 (
ECHO.TASKLIST Not supported by this OS
GOTO :eof
)

REM Verify that YourTask.exe is not running
TASKLIST /NH | FIND "YourTask.exe" > nul
SET Msg=Workstation is running.
IF NOT ERRORLEVEL 1 (
COLOR CF
ECHO.
ECHO.YourTask is running
ECHO.You must shut it down before running this program.
)
0 Kudos
ZygoCorp
Level 6

I need code that I can put into my .rul file and execute there. Can anyone help?
0 Kudos
rguggisberg
Level 13

Use LaunchAppAndWait to launch the bat file i posted above. Don't use the 'Hidden' option because if you have a PAUSE in the bat file you will wait forever.
0 Kudos
Reureu
Level 10

Here is some IS code you can use to find a running process with a specific name.


function BOOL findRunningProcess( hMsi, szProcessName )
OBJECT obj, wmi, slist;
STRING szSupportDir, filename, tmpStr;
VARIANT __varEnumHolder;
STRING query;
INT cnt, openDllSuccess;
BOOL result;
begin
// Read the support dir path (ie. where IsGetObj.dll is)
getSupportDir( hMsi, szSupportDir );

// Load IsGetObj.dll
filename = szSupportDir ^ "IsGetObj.dll";
openDllSuccess = UseDLL(filename);
cnt = 0;

if( openDllSuccess = 0 ) then
try
// Get the Windows Management Instrumentation (WMI) object
set wmi = CoGetObject("winmgmts:{impersonationLevel=impersonate}!//./root/cimv2", "" );

// Search for selected process
query = "Select * From Win32_Process Where Name Like '" + szProcessName + "'";
set slist = wmi.ExecQuery (query);

// Count the amount of processes that have the selected name
ForEachStart(slist, __varEnumHolder);
while(ERROR_SUCCESS == ForEachGetNextItem(__varEnumHolder, obj))
cnt++;
endwhile;

// Cleanup
set __varEnumHolder = NOTHING;
catch
tmpStr = "Exception raised when querying the process list";
log( hMsi, 1, tmpStr );
endcatch;

UnUseDLL("IsGetObj.dll");
else
Sprintf(tmpStr, "Could not open %s", filename );
log( hMsi, 1, tmpStr );
endif;

if( cnt != 0 ) then
result = TRUE;
tmpStr = szProcessName + " found in WMI's Win32_Process list" ;
else
result = FALSE;
tmpStr = "Could not find " + szProcessName + " in WMI's Win32_Process list";
endif;
log( hMsi, 1, tmpStr );

// and return the result
return result;
end;


You obviously need to implement your own log functions (or remove them from the above code), and your own getSupportDir:

  • If you are in a Basic or InstallScript MSI project, then getSupportDir should just retrieve the SUPPORTDIR property, possibly from the custom data.
  • If you are in an InstallScript project, then it should just retrieve the SUPPORTDIR variable.


And useless to say, the hMsi handle only makes sense for MSI projects.

As for IsGetObj.dll, it can be found here
http://www.installsite.org/files/GetObject.zip. Then you need to add it as support file.

I hope that helps.
0 Kudos
ZygoCorp
Level 6

Thank you very much. Added dll to support files. When I adjust the code for my logging and compile, I get "undefined identifier" on this line: ForEachStart(slist, __varEnumHolder);

It also has the same complaint about ERROR_SUCCESS and ForEachGetNextItem.
0 Kudos
Reureu
Level 10

Just add the following lines in your .rul file, before the function definition:


prototype ISGetObj.ForEachStart(byref OBJECT, byref VARIANT);
prototype ISGetObj.ForEachGetNextItem(byref VARIANT, byref OBJECT);


As for ERROR_SUCCESS, it is a predefined constant.
0 Kudos
ZygoCorp
Level 6

I thought it was because it was blue in the code line, but when I actually searched for it in the help, it isn't there. Now that I added the prototypes, the complaint about the ERROR_SUCCESS is the only one showing.

I really appreciate your help and patience. Thank you.
0 Kudos
Reureu
Level 10

ERROR_SUCCESS seems to be defined in Basic MSI only...
You can use ISERR_SUCCESS instead.
0 Kudos
ZygoCorp
Level 6

I was just typing the same thing when I got your reply!
0 Kudos
ZygoCorp
Level 6

all-righty - this seems to be working wonderfully on a Windows XP, 32bit system. This is my preliminary test system. thank you....

Problem: We are really running on Windows 7, 64-bit. Our process is a 64-bit process.

The wmi object is not created. after:
set wmi = CoGetObject("winmgmts:{impersonationLevel=impersonate}!//./root/cimv2", "" );

I added an IsObject(wmi) test, and this is returning no.
0 Kudos
savy17
Level 5

I have Basic MSI installation that I am working on.
I need to find out whether the application that I am upgrading/repairing is running or not. If running, then I don't want to continue with the installation.

I added the custom action named "CheckRunningProcess" that runs the script given over here. And also added IsGetObj.dll to Support Files.

However when I run the installer, it fails with the following error message in installer log

Action start 15:19:41: CheckRunningProcess.
Error 1720.There is a problem with this Windows Installer package. A script required for this install to complete could not be run. Contact your support personnel or package vendor. Custom action CheckRunningProcess script error -2146827286, Microsoft VBScript compilation error: Syntax error Line 1, Column 33, prototype ISGetObj.ForEachStart(byref OBJECT, byref VARIANT);
MSI (c) (DC:2C) [15:19:45:641]: Product: SampleInstaller -- Error 1720.There is a problem with this Windows Installer package. A script required for this install to complete could not be run. Contact your support personnel or package vendor. Custom action CheckRunningProcess script error -2146827286, Microsoft VBScript compilation error: Syntax error Line 1, Column 33, prototype ISGetObj.ForEachStart(byref OBJECT, byref VARIANT);

Action ended 15:19:45: CheckRunningProcess. Return value 3.

Not sure what I am doing wrong. Any suggestion please.
0 Kudos
Reureu
Level 10

Unfortunately, my crystal ball is out of order.
Maybe you should add some debugging code after each step of the function CheckRunningProcess.

Something like:
if( AskYesNo( "Installation stopped for debugging\nClick Yes to continue or No to abort?", YES ) = NO ) then
return ERROR_INSTALL_FAILURE;
endif;

between each operation.
Then you should be able to see exactly where it aborts.
0 Kudos
savy17
Level 5

It complains of Syntax error at the first line itself. So I am not able to proceed further. I don't have much knowledge of VB Script. I was just trying to copy and paste the code that was found in this thread. I am stuck.

Microsoft VBScript compilation error: Syntax error Line 1, Column 33, prototype ISGetObj.ForEachStart(byref OBJECT, byref VARIANT);

Any help please
0 Kudos
Reureu
Level 10

Well, the code I previously mentioned in the thread is InstallScript. It is not VB, although it does look similar.
If you want to use the code, you will need to create an InstallScript custom action.
Alternatively, you can rewrite it in VB, but I cannot help you with that.
Regards
0 Kudos
savy17
Level 5

Reureu wrote:
Well, the code I previously mentioned in the thread is InstallScript. It is not VB, although it does look similar.
If you want to use the code, you will need to create an InstallScript custom action.
Alternatively, you can rewrite it in VB, but I cannot help you with that.
Regards


Thanks Reureu for the quick response. I have created a vb script for the same purpose which is running fine with a small glitch and have posted the question on different thread. Thank you once again for your help.
0 Kudos