有时候卸载installshield安装的程序,卸载完会提示是否重启电脑以完成所有卸载,产生这个提示的常见原因有如下几种:
1. 卸载时,程序正处于运行状态
2. 卸载时,程序文件夹处于打开状态
3. 卸载时,有文件被别的进程调用,或者在进程中,常见情况如dll在进程中
一般来说解决办法是针对第三种情况的,解决办法是卸载时强制杀进程,比如在OnMaintUIBefore或者OnUninstall里写上强制杀进程的代码。对于第一种情况和第二种情况,如果是可交互的普通GUI程序,一般不予理会,因为这些行为是不能禁止的合理行为。
Installshield停止操作系统进程的代码 --IS6及以上版本适用
setup.rul的代码
Code
////////////////////////////////////////////////////////////////////////////////
//
//IIIIIII SSSSSS
//II SS InstallShield (R)
//II SSSSSS (c) 1996-2000, InstallShield Software Corporation
//II SS (c) 1990-1996, InstallShield Corporation
//IIIIIII SSSSSS All Rights Reserved.
//
//
//This code is generated as a starting setup template. You should
//modify it to provide all necessary steps for your setup.
//
//
//File Name: Setup.rul
//
//Description: InstallShield script
//
//Comments: This template script performs a basic setup. With minor
//modifications, this template can be adapted to create
//new, customized setups.
//
////////////////////////////////////////////////////////////////////////////////
//Include header files
#include"ifx.h"//DO NOT REMOVE
////////////////////// string defines////////////////////////////
//////////////////// installation declarations///////////////////
//----- DLL function prototypes -----
//your DLL function prototypes
#include"ShutDownRunningApp.rul"
//---- script function prototypes -----
//your script function prototypes
//your global variables
//////////////////////////////////////////////////////////////////////////////
//
//FUNCTION: OnFirstUIBefore
//
//EVENT: FirstUIBefore event is sent when installation is run for the first
//time on given machine. In the handler installation usually displays
//UI allowing end user to specify installation parameters. After this
//function returns, ComponentTransferData is called to perform file
//transfer.
//
///////////////////////////////////////////////////////////////////////////////
function OnFirstUIBefore()
NUMBER nResult,nSetupType;
STRING szTitle, szMsg;
begin
ifProcessRunning("notepad") then
MessageBox("Application is running.", INFORMATION);
ProcessEnd("notepad");
Delay(2);//Delay to allow process list to refresh
ifProcessRunning("notepad") then
MessageBox("Application is running.", INFORMATION);
else
MessageBox("Application is not running.", INFORMATION);
endif;
else
MessageBox("Application is not running.", 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)gotoDlg_Start;
//setup default status
SetStatusWindow(0,"");
Enable(STATUSEX);
StatusUpdate(ON,100);
return0;
end;
//////////////////////////////////////////////////////////////////////////////
//
//FUNCTION: OnFirstUIAfter
//
//EVENT: FirstUIAfter event is sent after file transfer, when installation
//is run for the first time on given machine. In this event handler
//installation usually displays UI that will inform end user that
//installation has been completed successfully.
//
///////////////////////////////////////////////////////////////////////////////
function OnFirstUIAfter()
begin
Disable(STATUSEX);
ShowObjWizardPages(NEXT);
end;
///////////////////////////////////////////////////////////////////////////////
//
//FUNCTION: OnMaintUIAfter
//
//EVENT: MaintUIAfter event is sent after file transfer, when end user runs
//installation that has already been installed on the machine. Usually
//this happens through Add/Remove Programs applet.
//In the handler installation usually displays UI that will inform
//end user that maintenance/uninstallation has been completed successfully.
//
///////////////////////////////////////////////////////////////////////////////
function OnMaintUIAfter()
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 a subfolder of TARGETDIR then add subfolder
szAppPath=TARGETDIR;
RegDBSetItem(REGDB_APPPATH, szAppPath);
RegDBSetItem(REGDB_APPPATH_DEFAULT, szAppPath^@PRODUCT_KEY);
end;
//--- include script file section ---
ShutDownRunningApp.rul的代码
Code
//////////////////////////////////////////////////////////////////////////////
//
//Description: Windows NT process control functions.
//
//The process code is adapted from code posted by William F.
//Snodgrass to www.installsite.org. The original code header
//is appended below. The array code is adapted from code posted
//by Rajesh Ramachandran to the installshield.is6.installscript
//newsgroup.
//
//Submitted by Richard Iwasa (riwasa@email.com).
//
//Usage example:
//
//if ProcessRunning("notepad") then
//MessageBox("Application is running.", INFORMATION);
//
//ProcessEnd("notepad");
//
//Delay(2);//Delay to allow process list to refresh
//
//if ProcessRunning("notepad") then
//MessageBox("Application is running.", INFORMATION);
//else
//MessageBox("Application is not running.", INFORMATION);
//endif;
//else
//MessageBox("Application is not running.", INFORMATION);
//endif;
//
//Original code header appended below:
//
//GetRunningApp();
//ShutDownApp();
//
//These script created functions will look for any running application
//based on the file name, then display an error message within the Setup.
//You can optionally halt the install or just continue on.
//
//You can use the ShutDownApp() function for shutting down that process
//or others as well. This is useful for processes that run in the
//background but have no Windows associated with them. May not work with
//Services.
//
//This script calls functions in PSAPI.DLL that are not supported on
//Windows 95 or 98.
//
//Instructions
//Place these script peices into the Setup.rul file.
//
//Modify the script to include the applications you would like to get or
//shutdown.
//
//Submitted by William F. Snodgrass
//Contact info: bsnodgrass@geographix.com
//
//Created by Theron Welch, 3/3/99
//Minor modifications by Stefan Krueger, 11/03/99
//
//Copyright (c) 1999-2000 GeoGraphix, Inc.
//
//////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////
//Function prototypes.
/////////////////////////////////////////////////
prototype POINTER ArrayToPointer(BYREF VARIANT);
prototype NUMBER ProcessEnd(STRING);
prototype BOOL ProcessRunning(STRING);
//Kernel functions.
prototype NUMBER Kernel32.OpenProcess(NUMBER, BOOL, NUMBER);
prototype NUMBER Kernel32.TerminateProcess(NUMBER, NUMBER);
//Process information functions.
prototype NUMBER PSAPI.EnumProcesses(POINTER, NUMBER, BYREF NUMBER);
prototype NUMBER PSAPI.EnumProcessModules(NUMBER, BYREF NUMBER, NUMBER,
BYREF NUMBER);
prototype NUMBER PSAPI.GetModuleFileNameExA(NUMBER, NUMBER, BYREF STRING,
NUMBER);
/////////////////////////////////////////////////
//Structures.
/////////////////////////////////////////////////
//Structure to mirror the C/C++ SAFEARRAY data structure.
typedef _SAFEARRAY
begin
SHORT cDims;
SHORT fFeatures;
LONG cbElements;
LONG cLocks;
POINTER pvData;
//rgsaBound omitted
end;
//Structure to mirror the C/C++ VARIANT data structure.
typedef _VARIANT
begin
SHORT vt;
SHORT wReserver1;
SHORT wReserved2;
SHORT wReserved3;
NUMBER nData;
end;
/////////////////////////////////////////////////
//Constants.
/////////////////////////////////////////////////
#definePSAPI_FILE "psapi.dll"//Windows NT process DLL
#definePROCESSID_LENGTH 4//4 bytes (DWORD) for a process ID
//Process information constants.
#definePROCESS_QUERY_INFORMATION 0x400
#definePROCESS_ALL_ACCESS 0x1f0fff
#definePROCESS_VM_READ 0x10
//////////////////////////////////////////////////////////////////////////////
//
//Function: ArrayToPointer
//
//Description: Converts an InstallShield array into a C array.
//
//When an array is created in InstallScript, a VARIANT variable
//is created which holds an OLEAutomation SAFEARRAY. To pass
//such an array to a DLL function expecting a C-style array,
//this function explicitly typecasts the pointer to the array
//to a _VARIANT pointer so that the _SAFEARRAY pointer can be
//extracted. The pointer to the actual data is then extracted
//from the _SAFEARRAY pointer.
//
//Parameters: structArray - Array variable.
//
//Returns: POINTER - Pointer to array.
//
//////////////////////////////////////////////////////////////////////////////
function POINTER ArrayToPointer(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 data from the _SAFEARRAY.
returnpstructArray->pvData;
end;
//////////////////////////////////////////////////////////////////////////////
//
//Function: _Process_End
//
//Description: Terminates running processes for the specified application.
//
//Parameters: szAppName - Name of the application to terminate.
//
//Returns: >= 0 - Number of processes terminated.
//-1 - Failure.
//
//////////////////////////////////////////////////////////////////////////////
function NUMBER ProcessEnd(szAppName)
NUMBER nvReturn;//Number of processes terminated
NUMBER nvProcessIDs(512);//Array of process IDs
NUMBER nvBytesReturned;//Number of bytes returned in process ID array
NUMBER nvProcesses;//Number of processes running
NUMBER nvIndex;//Loop index
NUMBER nvProcessHandle;//Handle to a process
NUMBER nvModuleHandle;//Handle to a process module
NUMBER nvBytesRequired;//Number of bytes required to store values
POINTER pvProcessIDs;//Pointer to process ID array
STRING svModuleName;//Module name
STRING svFileName;//Module filename
begin
//The psapi.dll reads the Windows NT performance database. The DLL
//is part of the Win32 SDK.
ifUseDLL(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 running processes.
pvProcessIDs=ArrayToPointer(nvProcessIDs);
EnumProcesses(pvProcessIDs,512, nvBytesReturned);
//Determine the number of process IDs retrieved. Each process ID
//is PROCESSID_LENGTH bytes.
nvProcesses=nvBytesReturned/PROCESSID_LENGTH;
//Get the executable associated with each process, and check if
//its filename matches the one passed to the function.
fornvIndex=1to nvProcesses
//Get a handle to the process. The OpenProcess function
//must have full (all) access to be able to terminate
//processes.
nvProcessHandle=OpenProcess(PROCESS_QUERY_INFORMATION|
PROCESS_ALL_ACCESS,0, nvProcessIDs(nvIndex));
ifnvProcessHandle!=0then
//Get a handle to the first module in the process, which
//should be the executable.
ifEnumProcessModules(nvProcessHandle, nvModuleHandle,
PROCESSID_LENGTH, nvBytesRequired)!=0then
//Get the path of the module.
ifGetModuleFileNameExA(nvProcessHandle, nvModuleHandle,
svModuleName, SizeOf(svModuleName))!=0then
//Extract the filename (without an extension) from
//the path.
ParsePath(svFileName, svModuleName, FILENAME_ONLY);
ifStrCompare(svFileName, szAppName)=0then
//The process module matches the application
//name passed to the function.
ifTerminateProcess(nvProcessHandle,0)>0then
nvReturn++;
endif;
endif;
endif;
endif;
endif;
endfor;
ifUnUseDLL(PSAPI_FILE)<0then
MessageBox("ERROR: Could not unload ["+WINSYSDIR^PSAPI_FILE+
"].", SEVERE);
return-1;
endif;
returnnvReturn;
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 not running.
//
//////////////////////////////////////////////////////////////////////////////
function BOOL ProcessRunning(szAppName)
BOOL bvRunning;//Process is running
NUMBER nvProcessIDs(512);//Array of process IDs
NUMBER nvBytesReturned;//Number of bytes returned in process ID array
NUMBER nvProcesses;//Number of processes running
NUMBER nvIndex;//Loop index
NUMBER nvProcessHandle;//Handle to a process
NUMBER nvModuleHandle;//Handle to a process module
NUMBER nvBytesRequired;//Number of bytes required to store values
POINTER pvProcessIDs;//Pointer to process ID array
STRING svModuleName;//Module name
STRING svFileName;//Module filename
begin
//The psapi.dll reads the Windows NT performance database. The DLL
//is part of the Win32 SDK.
ifUseDLL(WINSYSDIR^PSAPI_FILE)<0then
//Could not load psapi.dll.
MessageBox("ERROR: Could not load ["+WINSYSDIR^PSAPI_FILE+
"].", SEVERE);
returnFALSE;
endif;
//Get the PIDs of all currently running processes.
pvProcessIDs=ArrayToPointer(nvProcessIDs);
EnumProcesses(pvProcessIDs,512, nvBytesReturned);
//Determine the number of process IDs retrieved. Each process ID
//is PROCESSID_LENGTH bytes.
nvProcesses=nvBytesReturned/PROCESSID_LENGTH;
//Get the executable associated with each process, and check if
//its filename matches the one passed to the function.
fornvIndex=1to nvProcesses
//Get a handle to the process.
nvProcessHandle=OpenProcess(PROCESS_QUERY_INFORMATION|
PROCESS_VM_READ,0, nvProcessIDs(nvIndex));
ifnvProcessHandle!=0then
//Get a handle to the first module in the process, which
//should be the executable.
ifEnumProcessModules(nvProcessHandle, nvModuleHandle,
PROCESSID_LENGTH, nvBytesRequired)!=0then
//Get the path of the module.
ifGetModuleFileNameExA(nvProcessHandle, nvModuleHandle,
svModuleName, SizeOf(svModuleName))!=0then
//Extract the filename (without an extension) from
//the path.
ParsePath(svFileName, svModuleName, FILENAME_ONLY);
ifStrCompare(svFileName, szAppName)=0then
//The process module matches the application
//name passed to the function.
bvRunning=TRUE;
gotoProcessRunningEnd;
endif;
endif;
endif;
endif;
endfor;
ProcessRunningEnd:
ifUnUseDLL(PSAPI_FILE)<0then
MessageBox("ERROR: Could not unload ["+WINSYSDIR^PSAPI_FILE+
"].", SEVERE);
returnFALSE;
endif;
returnbvRunning;
end;
Installshield停止操作系统进程的代码--IS5版本适用
出处:http://www.installsite.org/pages/en/isp_ext.htm
这个地址上有不少好东西,有空要好好研究下
里面的“List and Shut Down Running Applications”就是演示了Installshield如何停止操作系统进程
Code
/***********
/ GetRunningApp();
/ ShutDownApp();
/
/ These script created functions will look for any running application based on
/ the file name, then display an error message within the Setup. You can optionally
/ halt the install or just continue on.
/
/ You can use the ShutDownApp() function for shutting down that process or others
/ as well. This is useful for processes that run in the background but have no Windows
/ associated with them. May not work with Services.
/
/ This script calls functions in PSAPI.DLL that are not supported on Windows 95 or 98.
/
/* Instructions
/ Place these script peices into the Setup.rul file.
/
/ Modify the script to include the applications you would like to get or shutdown.
/
/ Submitted by William F. Snodgrass
/ Contact info: bsnodgrass@geographix.com
/
/ Created by Theron Welch, 3/3/99
/ Minor modifications by Stefan Krueger, 11/03/99
/
/ Copyright (c) 1999-2000 GeoGraphix, Inc.
***********/
//////////////////// installation declarations///////////////////
//----- DLL function prototypes -----
//your DLL function prototypes
//Custom function for shutting down MyApp process
prototype ShutDownApp();
//Custom function for shutting down any running application
prototype GetRunningApp( BYREF STRING );
///////////////////////////////////////////////////////////////////////////////////
//Dll function calls needed
//Kernel functions
prototype LONG Kernel32.OpenProcess( LONG, BOOL, LONG );//1ST Param = 2035711 for PROCESS_ALL_ACCESS (It pays to know hex!!), 2nd = Doesn't matter, 3rd = Process ID
prototype BOOL Kernel32.TerminateProcess( LONG, INT );//1st Param = Process ID, 2nd = Doesn't matter - "0"
//Process info functions
prototype LONG Psapi.EnumProcesses( POINTER, LONG, BYREF LONG );//1st Param = By ref, Process ID, 2nd = number of bytes in param 1 = "4", 3rd = cb needed - might as well be "4"
prototype LONG Psapi.GetModuleFileNameExA( LONG, LONG, POINTER, LONG );//1st Param = ProcessID, 2nd= Module ID, 3rd = pointer to a string, 4th = length of string
prototype LONG Psapi.EnumProcessModules( LONG, BYREF LONG, LONG, BYREF LONG );//1st Param = Process Handle, 2nd = Module Handle, 3rd = bytes passed ("4"), 4th = bytes needed ("4")
///////////////////////////////////////////////////////////////////////////////////
//your global variables
STRING svApp
program
if(1==GetRunningApp ( svApp ) ) then
MessageBox ("The installation has detected that"+svApp+"is running."+
"Please close"+svApp+"then restart the installation process.", SEVERE );
abort;
endif;
if(0==ShutDownProjectManager() )gotoend_install;//This statement is within the Program block and jumps to the
"end_install:"switchifthe function fails.-WFS
endprogram
///////////////////////////////////////////////////////////////////////////////////
//
//Function: GetRunningApp
//
//Purpose: This function returns "1" if an app is running. Otherwise "0".
//If "1" is returned, the "appName" parameter will contain the name of the
//application running.
//
//Theron Welch 3/3/99
//
///////////////////////////////////////////////////////////////////////////////////
function GetRunningApp( appName )
HWND hWnd;
LONG ProcessIDs[512];//An array that's hopefully big enough to hold all process IDs
LONG cbNeeded;
LONG cb;
LONG numItems;
LONG ProcessHandle;
LONG ModuleHandle;
LONG Count;
LONG Ret;
LONG Ret2;
POINTER pArray;//This pointer will point at the array of process IDs
STRING ModuleName[128];
STRING FileName[64];
POINTER pModuleName;
begin
UseDLL ( WINSYSDIR^"Psapi.dll");//Load the helper dll - PsApi.dll
cbNeeded=96;
cb=8;
pArray=&ProcessIDs;//Point at the array
while( cb<=cbNeeded )
cb=cb2;
EnumProcesses ( pArray, cb, cbNeeded );//Get the currently running process IDs
endwhile;
numItems=cbNeeded/4;//Calculate number of process IDs - 4 is the size in bytes of a Process ID (DWORD)
forCount=1to numItems//For each process id
ProcessHandle=OpenProcess (2035711,1, ProcessIDs[ Count ] );//Get a handle to the process
if(0!=ProcessHandle ) then
Ret=EnumProcessModules ( ProcessHandle, ModuleHandle,4, cb );//Get the module handle - first one is EXE, the one I care about!
if(0!=Ret ) then
pModuleName=&ModuleName;//Point at the array
Ret=GetModuleFileNameExA ( ProcessHandle, ModuleHandle, pModuleName,128);//Get the exe name
if(0!=Ret ) then
ParsePath ( FileName, ModuleName, FILENAME_ONLY );//Convert the full path to a filename
//////////////////////////////Outlook/////////////////////////////////////////
//Copy the next 5 lines and customize for each app
Ret=StrCompare ( FileName,"Outlook");
if(0==Ret ) then//If there's a match
FileName="Microsoft Outlook";//Change to a name that makes sense
appName=FileName;//Copy the filename to the passed in parameter (by ref)
return1;//Return "Found"
endif;
///////////////////////////////////////////////////////////////////////////////
//////////////////////////////Navwnt/////////////////////////////////////////
Ret=StrCompare ( FileName,"Navwnt");
if(0==Ret ) then//If there's a match
FileName="Norton Anti-Virus";//Change to a name that makes sense
appName=FileName;//Copy the filename to the passed in parameter (by ref)
return1;//Return "Found"
endif;
///////////////////////////////////////////////////////////////////////////////
endif;
endif;
endif;
endfor;
return0;//"Well, uh, apparently, no application is running"
end;
///////////////////////////////////////////////////////////////////////////////////
//
//Function: ShutDownApp
//
//Purpose: This function attempts to shut down the app you decide on. It returns
//"1" if successful or if app is not running.
//Otherwise "0" if it could not be shut down. Install should terminate
//if "0" is returned.
//
//Theron Welch 3/3/99
//
///////////////////////////////////////////////////////////////////////////////////
function ShutDownApp()
HWND hWnd;
LONG ProcessIDs[512];//An array that's hopefully big enough to hold all process IDs
LONG cbNeeded;
LONG cb;
LONG numItems;
LONG ProcessHandle;
LONG ModuleHandle;
LONG Count;
LONG Ret;
LONG Ret2;
POINTER pArray;//This pointer will point at the array of process IDs
STRING ModuleName[128];
STRING FileName[64];
POINTER pModuleName;
begin
UseDLL ( WINSYSDIR^"Psapi.dll");//Load the helper dll - PsApi.dll
cbNeeded=96;
cb=8;
pArray=&ProcessIDs;//Point at the array
while( cb<=cbNeeded )
cb=cb2;
EnumProcesses ( pArray, cb, cbNeeded );//Get the currently running process IDs
endwhile;
numItems=cbNeeded/4;//Calculate number of process IDs - 4 is the size in bytes of a Process ID (DWORD)
forCount=1to numItems//For each process id
ProcessHandle=OpenProcess (2035711,1, ProcessIDs[ Count ] );//Get a handle to the process
if(0!=ProcessHandle ) then
Ret=EnumProcessModules ( ProcessHandle, ModuleHandle,4, cb );//Get the module handle - first one is EXE, the one I care about!
if(0!=Ret ) then
pModuleName=&ModuleName;//Point at the array
Ret=GetModuleFileNameExA ( ProcessHandle, ModuleHandle, pModuleName,128);//Get the exe name
if(0!=Ret ) then
ParsePath ( FileName, ModuleName, FILENAME );//Convert the full path to a filename
//MessageBox( FileName, INFORMATION );
Ret=StrCompare ( FileName,"MYAPP~1.EXE");//Compare filenames (used for short file names. -WFS)
Ret2=StrCompare ( FileName,"MYAPP.exe");//Compare filenames
if(0==Ret||0==Ret2 ) then//If it's the filename I'm looking for
Ret=TerminateProcess( ProcessHandle,0);//Terminate the process
if(0==Ret ) then
gotoError;
endif;
gotoQuit;
endif;
endif;
endif;
endif;
endfor;
Quit:
UnUseDLL ("Psapi.dll");//Unload the helper dll - PsApi.dll
return1;//Happy
Error:
UnUseDLL ("Psapi.dll");//Unload the helper dll - PsApi.dll
return0;//Sad
end;原文链接: https://www.cnblogs.com/BeyondTechnology/archive/2010/10/14/1851712.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/16142
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!