Installshield 在安装或者卸载过程中,判断某一程序是否正在运行
1.在操作时,首先引入类库ShutDownRunningApp.rul,其中ShutDownRunningApp.rul代码如下
////////////////////////////////////////////////////////////////////////////// // // Description: WindowsNT process control functions. // // The process code is adapted fromcode posted by William F. // Snodgrass to www.installsite.org.The original code header // is appended below. The array codeis adapted from code posted // by Rajesh Ramachandran to theinstallshield.is6.installscript // newsgroup. // // Submitted by RichardIwasa (riwasa@email.com). // // Usage example: // // ifProcessRunning("notepad") then // MessageBox("Application isrunning.", INFORMATION); // // ProcessEnd("notepad"); // // Delay(2); // Delay to allow process list to refresh // // if ProcessRunning("notepad")then // MessageBox("Application isrunning.", INFORMATION); // else // MessageBox("Application is notrunning.", INFORMATION); // endif; // else // MessageBox("Application is notrunning.", INFORMATION); // endif; // // Original code headerappended below: // // GetRunningApp(); // ShutDownApp(); // // These script createdfunctions will look for any running application // based on the filename, then display an error message within the Setup. // You can optionally haltthe install or just continue on. // // You can use theShutDownApp() function for shutting down that process // or others as well.This is useful for processes that run in the // background but haveno Windows associated with them. May not work with // Services. // // This script callsfunctions in PSAPI.DLL that are not supported on // Windows 95 or 98. // // ***Instructions*** // Place these scriptpeices into the Setup.rul file. // // Modify the script toinclude the applications you would like to get or // shutdown. // // Submitted by WilliamF. Snodgrass // Contact info:bsnodgrass@geographix.com // // Created by TheronWelch, 3/3/99 // Minor modificationsby Stefan Krueger, 11/03/99 // // Copyright (c)1999-2000 GeoGraphix, Inc. // ////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////// // Function prototypes. ///////////////////////////////////////////////// prototype POINTERArrayToPointer(BYREF VARIANT); prototype NUMBER ProcessEnd(STRING); prototype BOOL ProcessRunning(STRING); // Kernel functions. prototype NUMBERKernel32.OpenProcess(NUMBER, BOOL, NUMBER); prototype NUMBERKernel32.TerminateProcess(NUMBER, NUMBER); // Process informationfunctions. prototype NUMBERPSAPI.EnumProcesses(POINTER, NUMBER, BYREF NUMBER); prototype NUMBERPSAPI.EnumProcessModules(NUMBER, BYREF NUMBER, NUMBER, BYREF NUMBER); prototype NUMBERPSAPI.GetModuleFileNameExA(NUMBER, NUMBER, BYREF STRING, NUMBER); ///////////////////////////////////////////////// // Structures. ///////////////////////////////////////////////// // Structure to mirrorthe C/C++ SAFEARRAY data structure. typedef _SAFEARRAY begin SHORT cDims; SHORT fFeatures; LONG cbElements; LONG cLocks; POINTER pvData; // rgsaBound omitted end; // Structure to mirrorthe C/C++ VARIANT data structure. typedef _VARIANT begin SHORT vt; SHORT wReserver1; SHORT wReserved2; SHORT wReserved3; NUMBER nData; end; ///////////////////////////////////////////////// // Constants. ///////////////////////////////////////////////// #define PSAPI_FILE "psapi.dll" // Windows NT process DLL #define PROCESSID_LENGTH 4 // 4 bytes (DWORD) for a process ID // Process informationconstants. #definePROCESS_QUERY_INFORMATION 0x400 #definePROCESS_ALL_ACCESS 0x1f0fff #definePROCESS_VM_READ 0x10 ////////////////////////////////////////////////////////////////////////////// // // Function: ArrayToPointer // // Description: Convertsan InstallShield array into a C array. // // When an array is created inInstallScript, a VARIANT variable // is created which holds anOLEAutomation SAFEARRAY. To pass // such an array to a DLL functionexpecting a C-style array, // this function explicitlytypecasts the pointer to the array // to a _VARIANT pointer so that the_SAFEARRAY pointer can be // extracted. The pointer to theactual data is then extracted // from the _SAFEARRAY pointer. // // Parameters: structArray - Array variable. // // Returns: POINTER - Pointer to array. // ////////////////////////////////////////////////////////////////////////////// function POINTERArrayToPointer(structArray) _SAFEARRAY POINTER pstructArray; // _SAFEARRAY array pointer _VARIANT POINTER pstructVariant; //_VARIANT array pointer begin // Typecast the pointer to the array to a_VARIANT pointer. pstructVariant = &structArray; // Extract the _SAFEARRAY pointer from the_VARIANT. pstructArray = pstructVariant->nData; // Return the pointer to the actual datafrom the _SAFEARRAY. return pstructArray->pvData; end; ////////////////////////////////////////////////////////////////////////////// // // Function: _Process_End // // Description:Terminates running processes for the specified application. // // Parameters: szAppName - Name of the application toterminate. // // Returns: >= 0 - Number of processes terminated. // -1 - Failure. // ////////////////////////////////////////////////////////////////////////////// function NUMBERProcessEnd(szAppName) NUMBER nvReturn; // Number ofprocesses terminated NUMBER nvProcessIDs(512); // Array ofprocess IDs NUMBER nvBytesReturned; // Number ofbytes returned in process ID array NUMBER nvProcesses; // Number ofprocesses running NUMBER nvIndex; // Loop index NUMBER nvProcessHandle; // Handle to aprocess NUMBER nvModuleHandle; // Handle to aprocess module NUMBER nvBytesRequired; // Number ofbytes required to store values POINTER pvProcessIDs; // Pointer to process ID array STRING svModuleName; // Module name STRING svFileName; // Modulefilename begin // The psapi.dll reads the Windows NTperformance database. The DLL // is part of the Win32 SDK. if UseDLL(WINSYSDIR ^ PSAPI_FILE) < 0then // Could not load psapi.dll. MessageBox("ERROR: Could not load[" + WINSYSDIR ^ PSAPI_FILE + "].", SEVERE); return -1; endif; // Get the PIDs of all currently runningprocesses. pvProcessIDs =ArrayToPointer(nvProcessIDs); EnumProcesses(pvProcessIDs, 512,nvBytesReturned); // Determine the number of process IDsretrieved. Each process ID // is PROCESSID_LENGTH bytes. nvProcesses = nvBytesReturned /PROCESSID_LENGTH; // Get the executable associated with eachprocess, and check if // its filename matches the one passed tothe function. for nvIndex = 1 to nvProcesses // Get a handle to the process. TheOpenProcess function // must have full (all) access to beable to terminate // processes. nvProcessHandle =OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_ALL_ACCESS, 0,nvProcessIDs(nvIndex)); if nvProcessHandle != 0 then // Get a handle to the first modulein the process, which // should be the executable. ifEnumProcessModules(nvProcessHandle, nvModuleHandle, PROCESSID_LENGTH,nvBytesRequired) != 0 then // Get the path of the module. ifGetModuleFileNameExA(nvProcessHandle, nvModuleHandle, svModuleName,SizeOf(svModuleName)) != 0 then // Extract the filename(without an extension) from // the path. ParsePath(svFileName,svModuleName, FILENAME_ONLY); if StrCompare(svFileName,szAppName) = 0 then // The process modulematches the application // name passed to thefunction. ifTerminateProcess(nvProcessHandle, 0) > 0 then nvReturn++; endif; endif; endif; endif; endif; endfor; if UnUseDLL(PSAPI_FILE) < 0 then MessageBox("ERROR: Could notunload [" + WINSYSDIR ^ PSAPI_FILE + "].", SEVERE); return -1; endif; return nvReturn; end; ////////////////////////////////////////////////////////////////////////////// // // Function: _Process_Running // // Description:Determines if the specified process is running in memory. // // Parameters: szAppName - Name of the application to check. // // Returns: TRUE - The process is running. // FALSE - The process is notrunning. // ////////////////////////////////////////////////////////////////////////////// function BOOLProcessRunning(szAppName) BOOL bvRunning; // Process isrunning NUMBER nvProcessIDs(512); // Array ofprocess IDs NUMBER nvBytesReturned; // Number ofbytes returned in process ID array NUMBER nvProcesses; // Number ofprocesses running NUMBER nvIndex; // Loop index NUMBER nvProcessHandle; // Handle to aprocess NUMBER nvModuleHandle; // Handle to aprocess module NUMBER nvBytesRequired; // Number ofbytes required to store values POINTER pvProcessIDs; // Pointer to process ID array STRING svModuleName; // Module name STRING svFileName; // Modulefilename begin // The psapi.dll reads the Windows NTperformance database. The DLL // is part of the Win32 SDK. if UseDLL(WINSYSDIR ^ PSAPI_FILE) < 0then // Could not load psapi.dll. MessageBox("ERROR: Could not load[" + WINSYSDIR ^ PSAPI_FILE + "].", SEVERE); return FALSE; endif; // Get the PIDs of all currently runningprocesses. pvProcessIDs =ArrayToPointer(nvProcessIDs); EnumProcesses(pvProcessIDs, 512,nvBytesReturned); // Determine the number of process IDsretrieved. Each process ID // is PROCESSID_LENGTH bytes. nvProcesses = nvBytesReturned /PROCESSID_LENGTH; // Get the executable associated with eachprocess, and check if // its filename matches the one passed tothe function. for nvIndex = 1 to nvProcesses // Get a handle to the process. nvProcessHandle =OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0,nvProcessIDs(nvIndex)); if nvProcessHandle != 0 then // Get a handle to the first modulein the process, which // should be the executable. ifEnumProcessModules(nvProcessHandle, nvModuleHandle, PROCESSID_LENGTH,nvBytesRequired) != 0 then // Get the path of the module. ifGetModuleFileNameExA(nvProcessHandle, nvModuleHandle, svModuleName,SizeOf(svModuleName)) != 0 then // Extract the filename(without an extension) from // the path. ParsePath(svFileName,svModuleName, FILENAME_ONLY); if StrCompare(svFileName,szAppName) = 0 then // The process modulematches the application // name passed to thefunction. bvRunning = TRUE; goto ProcessRunningEnd; endif; endif; endif; endif; endfor; ProcessRunningEnd: if UnUseDLL(PSAPI_FILE) < 0 then MessageBox("ERROR: Could notunload [" + WINSYSDIR ^ PSAPI_FILE + "].", SEVERE); return FALSE; endif; return bvRunning; end;
2.然后Setup.rul 代码如下:
//=========================================================================== // // File Name: Setup.rul // // Description: Blank setup main script file // // Comments: Blank setup is an empty setup project. If you want to // create a new project via. step-by step instructions use the // Project Assistant. // //=========================================================================== // Included header files---------------------------------------------------- #include"ifx.h" #include"ShutDownRunningApp.rul" // Note: In order tohave your InstallScript function executed as a custom // action by the WindowsInstaller, it must be prototyped as an // entry-point function. // The keyword exportidentifies MyFunction() as an entry-point function. // The argument itaccepts must be a handle to the Installer database. /* export prototypeMyFunction(HWND); */ function OnFirstUIBefore() NUMBER nResult,nSetupType; STRING szTitle, szMsg; begin if ProcessRunning("SOMME") then MessageBox("Application isrunning.", INFORMATION); ProcessEnd("SOMME"); Delay(2); // Delay to allow process list to refresh if ProcessRunning("SOMME")then MessageBox("Application isrunning.", INFORMATION); else MessageBox("Application is notrunning.", INFORMATION); endif; else MessageBox("Application is notrunning.", INFORMATION); endif; abort; // TO DO: if you want to enable background,window title, and caption bar title // SetTitle( @TITLE_MAIN, 24, WHITE ); // SetTitle( @TITLE_CAPTIONBAR, 0,BACKGROUNDCAPTION ); // Enable( FULLWINDOWMODE ); // Enable( BACKGROUND ); // SetColor(BACKGROUND,RGB (0, 128,128)); TARGETDIR = PROGRAMFILES ^@COMPANY_NAME^@PRODUCT_NAME; Dlg_Start: // beginning of dialogs label Dlg_ObjDialogs: nResult = ShowObjWizardPages(nResult); if (nResult = BACK) goto Dlg_Start; // setup default status SetStatusWindow(0, ""); Enable(STATUSEX); StatusUpdate(ON, 100); return 0; end; ////////////////////////////////////////////////////////////////////////////// // // FUNCTION: OnFirstUIAfter // // EVENT: FirstUIAfter event is sent after file transfer, when installation // is run for the first time ongiven machine. In this event handler // installation usually displays UIthat will inform end user that // installation has been completedsuccessfully. // /////////////////////////////////////////////////////////////////////////////// functionOnFirstUIAfter() begin Disable(STATUSEX); ShowObjWizardPages(NEXT); end; /////////////////////////////////////////////////////////////////////////////// // // FUNCTION: OnMaintUIAfter // // EVENT: MaintUIAfter event is sent after file transfer, when end user runs // installation that has alreadybeen installed on the machine. Usually // this happens through Add/RemovePrograms applet. // In the handler installationusually displays UI that will inform // end user thatmaintenance/uninstallation has been completed successfully. // /////////////////////////////////////////////////////////////////////////////// functionOnMaintUIAfter() begin Disable(STATUSEX); ShowObjWizardPages(NEXT); end; /////////////////////////////////////////////////////////////////////////////// // // FUNCTION: OnMoving // // EVENT: Moving event is sent when file transfer is started as a result of // ComponentTransferData call,before any file transfer operations // are performed. // /////////////////////////////////////////////////////////////////////////////// function OnMoving() STRING szAppPath; begin // Set LOGO Compliance Application Path // TO DO : if your application .exe is in asubfolder of TARGETDIR then add subfolder szAppPath = TARGETDIR; RegDBSetItem(REGDB_APPPATH, szAppPath); RegDBSetItem(REGDB_APPPATH_DEFAULT,szAppPath ^ @PRODUCT_KEY); end; //--------------------------------------------------------------------------- // OnBegin // // The OnBegin event iscalled directly by the framework after the setup // initializes. //--------------------------------------------------------------------------- function OnBegin() begin Disable (BACKBUTTON); if(!MAINTENANCE)then SdLicense2 ("License ", "Yes","False",SUPPORTDIR^"2.txt", FALSE); endif; end;