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

Uninstall Related Registry Deletion Question - InstallScript

OnEnd I run the following in my InstallScript package to make it so Add/Remove programs gets a size column:

RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
RegDBSetKeyValueEx ("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"+PRODUCT_GUID, "EstimatedSize", REGDB_NUMBER, "142606336", -1 );

I noticed that when I uninstall the product the key remains. So I tried adding this:

RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
RegDBDeleteValue("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"+PRODUCT_GUID,"EstimatedSize");

The code works in OnUninstall (when I pass a -uninst) to the command line, but when I add it to OnFirstMaintUIBefore or OnFirstMaintUIAfter it doesn't get executed, so it doesn't work if you just use Add/Remove programs. Anything special I can do to get this to work? Is my code just in the wrong function?

Labels (1)
0 Kudos
(8) Replies
MarkusLatz
Level 8

1st question is, why is it not automatically removed during uninstall.

Do you use somewhere in your script "Disable(LOGGING)" or just for debug purpose, try a "Enable(LOGGING)"

just before the registry operations.

regards

Markus

0 Kudos

@MarkusLatz that is a great question, one of which I don't know haha. I assumed it was because i was using code to add the key so InstallShield wasn't smart enough to know to remove it by default?

As for code in my project, the only lines of custom code are our own logging, here is my full .rul file.

// Included header files ----------------------------------------------------
#include "ifx.h"
#include "define.h"

//---------------------------------------------------------------------------
// OnSetTARGETDIR
//---------------------------------------------------------------------------
function OnSetTARGETDIR()
number nId, nIgnore, nResult;
string sCMDLINE, szId, szTARGETDIR;
begin

    // In maintenance mode the value of TARGETDIR is read from the log file.
    if( MAINTENANCE ) then
        return ISERR_SUCCESS;
    endif;

    // Set TARGETDIR to script default.
    TARGETDIR = PROGRAMFILES64 ^ "AIR\\Models";

    // Read TARGETDIR from the media.
    nResult = MediaGetData( MEDIA, MEDIA_FIELD_TARGETDIR, nIgnore, szTARGETDIR );

    // Use the TARGETDIR from the media if anything was read.
    if( nResult >= ISERR_SUCCESS && StrLengthChars( szTARGETDIR ) ) then
        TARGETDIR = szTARGETDIR;
    endif;
        
	// Customize the default TARGETDIR for multi-instance application.
	// TODO: If you want something different customize the code below.	
	if( MAINT_OPTION = MAINT_OPTION_MULTI_INSTANCE  && MULTI_INSTANCE_COUNT > 0) then

		// Start with the current multi-instance count plus one.
		nId = MULTI_INSTANCE_COUNT + 1;

		// Find a unique TARGETDIR.
		while( ExistsDir( TARGETDIR ) = EXISTS )
			
			// Convert to string.
			NumToStr( szId, nId );
			
			// Update IFX_MULTI_INSTANCE_SUFFIX
			IFX_MULTI_INSTANCE_SUFFIX = "_" + szId;
		
			// Update TARGETDIR
			TARGETDIR = TARGETDIR + IFX_MULTI_INSTANCE_SUFFIX;
			
			// Update nId
			nId = nId + 1;

		endwhile;

	endif;
	
	//Change TARGETDIR to CMDLINE from Suite Package
	sCMDLINE = CMDLINE;
	StrReplace (sCMDLINE, " ISFeatureInstall=ALL", "", 0); 
	TARGETDIR = sCMDLINE;

end;

//---------------------------------------------------------------------------
// OnBegin
//---------------------------------------------------------------------------
function OnBegin()

	NUMBER	nResult;

begin

    //Hide the Computer Icon
	DialogSetInfo (DLG_INFO_ALTIMAGE, "", TRUE);
	
	    // Get date and time for log name
	GetSystemInfo (DATE, nResult, sDate);
	StrReplace(sDate, "-", "", 0);
	GetSystemInfo (TIME, nResult, sTime);
	StrReplace(sTime, ":", "", 0);

	// Create the installer log file - stored in Logging.rul
	LogCreateFile();
	
    GetSystemInfo (DATE, nResult, sDate);
    StrReplace(sDate, "-", "/", 0);
	GetSystemInfo (TIME, nResult, sTime);
	
    LogCreateText(sInstallLog, "OnFirstUIBefore()              | Start Time: "+sDate+" "+sTime, 0, AFTER);
    
end;

//---------------------------------------------------------------------------                                                                        
// OnFirstUIBefore
//---------------------------------------------------------------------------
function OnFirstUIBefore()
    number  nResult, nLevel, nSize, nSetupType;
    string  szTitle, szMsg, szOpt1, szOpt2, szLicenseFile;
    string  szName, szCompany, szTargetPath, szDir, szFeatures;
    BOOL    bLicenseAccepted;
begin	

    // Added in InstallShield 15 - Show an appropriate error message if
    // -removeonly is specified and the product is not installed.
    if( REMOVEONLY ) then
        Disable( DIALOGCACHE );
		szMsg = SdLoadString( IDS_IFX_ERROR_PRODUCT_NOT_INSTALLED_UNINST );
   		SdSubstituteProductInfo( szMsg );
		MessageBox( szMsg, SEVERE );
		abort;
    endif;
   
    nSetupType = COMPLETE;	
    szDir = PROGRAMFILES64 ^ "AIR\\Models";
    bLicenseAccepted = FALSE;
    
    // Create a list for system information.
    LogCreateText(sInstallLog, "OnFirstUIBefore()              | Product Name: "+IFX_PRODUCT_NAME, 0, AFTER);
    LogCreateText(sInstallLog, "OnFirstUIBefore()              | Product Version: "+IFX_PRODUCT_VERSION, 0, AFTER);
    LogCreateText(sInstallLog, "OnFirstUIBefore()              | Package location: "+SRCDIR, 0, AFTER);

// Beginning of UI Sequence
Dlg_Start:
    nResult = 0;

Dlg_SdWelcome:
    szTitle = "";
    szMsg = "";
    //{{IS_SCRIPT_TAG(Dlg_SdWelcome)
    nResult = SdWelcome( szTitle, szMsg );
    //}}IS_SCRIPT_TAG(Dlg_SdWelcome)
    if (nResult = BACK) goto Dlg_Start;

Dlg_AskDestPath:

	nResult = SdAskDestPath ("", "", szDir, 0);
	if (nResult = BACK) goto Dlg_SdWelcome;

	TARGETDIR = szDir;
	StrRemoveLastSlash (szDir);
	LogCreateText(sInstallLog, "OnFirstUIBefore()              | Installation Directory: "+TARGETDIR, 0, AFTER);

    // Added in 11.0 - Set appropriate StatusEx static text.
    SetStatusExStaticText( SdLoadString( IDS_IFX_STATUSEX_STATICTEXT_FIRSTUI ) );
 
    return 0;
end;

//---------------------------------------------------------------------------
// OnInstalledFile
//---------------------------------------------------------------------------
function OnInstalledFile(szFile)
begin

	LogCreateText(sInstallLog, "OnInstalledFile()              | File Copied: "+szFile, 0, AFTER); 

end;

//---------------------------------------------------------------------------
// OnFirstUIAfter
//---------------------------------------------------------------------------
function OnFirstUIAfter()
    STRING szTitle, szMsg1, szMsg2, szOpt1, szOpt2;
    NUMBER bvOpt1, bvOpt2, nResult;
begin

    ShowObjWizardPages(NEXT);
    
    szTitle = "";
    szMsg1 = ""; 
    szMsg2 = "";
    szOpt1 = "";
    szOpt2 = "";
	bvOpt1   = FALSE;
    bvOpt2   = FALSE;  
    
    
    // Get date and time for log name
	GetSystemInfo (DATE, nResult, sDate);
	StrReplace(sDate, "-", "/", 0);
	GetSystemInfo (TIME, nResult, sTime); 
    
    //{{IS_SCRIPT_TAG(Dlg_SdDinishEx)	
    if ( BATCH_INSTALL ) then
    	SdFinishReboot ( szTitle , szMsg1 , SYS_BOOTMACHINE , szMsg2 , 0 );
    else
	    SdFinish ( szTitle , szMsg1 , szMsg2 , szOpt1 , szOpt2 , bvOpt1 , bvOpt2 );
	endif;
    //}}IS_SCRIPT_TAG(Dlg_SdDinishEx)	
    
    LogCreateText(sInstallLog, "OnFirstUIAfter()               | Finish Time: "+sDate+" "+sTime, 0, AFTER); 
end;

//---------------------------------------------------------------------------
// OnEnd
//---------------------------------------------------------------------------
function OnEnd()
begin

	//Set the Install Size in Programs and Features (in KB)
	RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
	RegDBSetKeyValueEx ("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"+PRODUCT_GUID, "EstimatedSize", REGDB_NUMBER, SIZE_INSTALLED, -1 );

end;

//---------------------------------------------------------------------------
// OnUninstall
//---------------------------------------------------------------------------
function OnUninstall()
string sKey, szIgnore, szMsg;
number nResult;
BOOL bOpt1, bOpt2;
begin

    // Hide the initial progress dialog.
    Disable( DIALOGCACHE );

    // Added in InstallShield 15 - Show an appropriate error message if
    // -uninst is specified and the product is not installed.
    if( !MAINTENANCE ) then
		szMsg = SdLoadString( IDS_IFX_ERROR_PRODUCT_NOT_INSTALLED_UNINST );
   		SdSubstituteProductInfo( szMsg );
		MessageBox( szMsg, SEVERE );
		abort;
    endif;
	
	// Show Uninstall Confirmation Dialog
	if( MessageBox( SdLoadString( IFX_MAINTUI_MSG ), MB_YESNO ) != IDYES ) then
        abort;
    endif;
    
    //Cleanup Key we created to manipulate sizing
	RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
	RegDBDeleteValue("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"+PRODUCT_GUID,"EstimatedSize");

    // Remove all features.
	FeatureRemoveAllInMediaAndLog();

    // Added in 11.0, disable the cancel button during uninstall.
    if( REMOVEALLMODE ) then
        Disable( CANCELBUTTON );
    endif;
    
	// Added in 11.0 - Set appropriate StatusEx static text.
	// Moved in 12.1 - Set before calling Enable( STATUSEX ) to ensure proper product name updating.
    SetStatusExStaticText( SdLoadString( IDS_IFX_STATUSEX_STATICTEXT_MAINTUI_REMOVEALL ) );

    // Show Status
	SetStatusWindow( 0, "" );
	Enable( STATUSEX );
	StatusUpdate( ON, 100 );

    // Uninstall
	nResult = FeatureTransferData( MEDIA );

    // Handle move data error and abort if error occured.
	if( nResult < ISERR_SUCCESS ) then
		OnComponentError();
		abort;
	endif;

    // Disable Status
	Disable( STATUSEX );

    // Show final dialog.
    if ( BATCH_INSTALL ) then
        SdFinishReboot( SdLoadString(IFX_SDFINISH_REMOVE_TITLE), SdLoadString(IFX_SDFINISH_REMOVE_MSG2), SYS_BOOTMACHINE, "", 0 );
    else    
        SdFinish( SdLoadString(IFX_SDFINISH_REMOVE_TITLE), SdLoadString(IFX_SDFINISH_REMOVE_MSG1), "", "" , "", bOpt1 , bOpt2 );
    endif;
 
end;

//---------------------------------------------------------------------------
// OnMaintUIBefore
//---------------------------------------------------------------------------
function OnMaintUIBefore()
    number	nResult, nType;
    string	szTitle, szMsg;
begin
	
	// nType defaults to MODIFY.
	nType = MODIFY;

    //Initialize SQL
    OnSQLServerInitializeMaint();

// Beginning of UI Sequence
Dlg_Start:

    // Added in Version 9.5 - Support for REMOVEONLY option.
    if( !REMOVEONLY ) then
    	// In standard mode show maintenance dialog
	    Disable( BACKBUTTON );
	    nType = SdWelcomeMaint( szTitle, szMsg, nType );
	    Enable( BACKBUTTON );
        nResult = NEXT;
    else
        // Hide the initial progress dialog as otherwise the user can
        // click on it, and hide the MessageBox.
        Disable( DIALOGCACHE );

        // In RemoveOnly mode, set to remove.
        nType = REMOVEALL;
    endif;

	// Show Uninstall Confirmation Dialog
    if ( nType = REMOVEALL ) then
		nResult = MessageBox( SdLoadString( IFX_MAINTUI_MSG ), MB_YESNO );
		if (nResult != IDYES ) then
            
            if( REMOVEONLY ) then
                // In REMOVEONLY mode, abort the setup.
                abort;
            else
                // In non-REMOVEONLY mode, redisplay the previous dialog.
			    goto Dlg_Start;
            endif;

		endif;
	endif;

Dlg_SdFeatureTree:
	if ( nType = MODIFY ) then
		szTitle = "";
		szMsg = SdLoadString( SD_STR_COMPONENT_MAINT_MSG );
		nResult = SdFeatureTree( szTitle, szMsg, TARGETDIR, "", -1 );
		if ( nResult = BACK ) goto Dlg_Start;
    endif;

Dlg_ObjDialogs:
    nResult = ShowObjWizardPages( nResult );
    if ( ( nResult = BACK ) && ( nType != MODIFY ) ) goto Dlg_Start;
    if ( ( nResult = BACK ) && ( nType = MODIFY ) ) goto Dlg_SdFeatureTree;

	switch(nType)

        case REMOVEALL:
        			
			// Ensure that all previously installed features are removed.
			FeatureRemoveAllInMediaAndLog();

            // Added in 11.0 - Set appropriate StatusEx static text.
            SetStatusExStaticText( SdLoadString( IDS_IFX_STATUSEX_STATICTEXT_MAINTUI_REMOVEALL ) );

        case REPAIR:
				
			// Changed for DevStudio 9, Disk1 files are now always updated when installed
			// so when running from ADDREMOVE we need to prevent these files from being
			// updated since this will result in files being updated that are locked by the setup.
			// Updating these files when running from ADDREMOVE should not be needed since updates
			// are not run directly from Add/Remove.
            if( ADDREMOVE ) then
                // Reinstall all previously installed features, except
                // disk1 features.
                FeatureUpdate( "" );
            else
                // Reinstall all previously installed features.
                FeatureReinstall();
            endif;

            // Added in 11.0 - Set appropriate StatusEx static text.
            SetStatusExStaticText( SdLoadString( IDS_IFX_STATUSEX_STATICTEXT_MAINTUI_REPAIR ) );

        case MODIFY:
            
            // Added in 11.0 - Set appropriate StatusEx static text.
            SetStatusExStaticText( SdLoadString( IDS_IFX_STATUSEX_STATICTEXT_MAINTUI_MODIFY ) );

    endswitch;
    
    if ( nType = REMOVEALL ) then
		//Cleanup Key we created to manipulate sizing
		RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
		RegDBDeleteValue("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"+PRODUCT_GUID,"EstimatedSize");  
	endif;
 
end;
0 Kudos

Okay, I try to test this on my site in the evening. May be I find a hint why it does not work ?

regards

Markus

0 Kudos

oddly enough message boxes pop up where the delete code is, so its definitely reaching that code. and if that code is in OnUninstall it deletes the key.

0 Kudos

@MarkusLatz , so i added more code around it for debugging and it seems the keys aren't found... maybe something is broke in OnMaintUIBefore? I tried the following key and its failing (a key that should exist in both Wow6432 and non.

 

// Set the root key.
		RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
		
		// Set the name of the subkey.
		szSubKey = "SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
		szValue  = "EstimatedSize";
		
		if (RegDBKeyExist (szSubKey) < 0) then	
			// Delete the subkey.
			nReturn2 = RegDBDeleteValue (szSubKey, szValue);
			
			// Report the results of the deletion.
			if (nReturn2 < 0) then
				MessageBox ("RegDBDeleteValue failed.", SEVERE);
			else
				SprintfBox (INFORMATION, "Blah", "%s successfully deleted.", szValue);
			endif;
		else
			MessageBox("Key not found: "+szSubKey, WARNING);
		endif;
0 Kudos

Hi @DonAIR ,

I write this post the 2nd time, because the 1st one was lost .

Okay, I played a bit with a similar InstallScript project I have and moved my function to write additional installation infos for uninstall to the "OnEnd" event.

And now my registry keys remain also.

So I took a look to the manual, and oops, the "OnEnd" event is executed "always".

So that my code works I have written:

function OnEnd()

  string svIcon;

begin

  if (!MAINTENANCE) then
    svIcon = TARGETDIR ^ "InstInfo" ^ "Lcs.ico";
    AddInstallationInfo(svIcon);
  endif;

end;

And after that it works as it should. Can you try this also. Let me know if it worked now.

regards

Markus

0 Kudos

Just that it is clear:

function OnEnd()
begin

  if (!MAINTENANCE) then
    //Set the Install Size in Programs and Features (in KB)
	  RegDBSetDefaultRoot (HKEY_LOCAL_MACHINE);
	  RegDBSetKeyValueEx ("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"+PRODUCT_GUID, "EstimatedSize", REGDB_NUMBER, SIZE_INSTALLED, -1 );
  endif;

end;
0 Kudos

@MarkusLatz priceless, I am a dolt. So essentially all my code worked wonderfully, but I was trying to delete a key that had already been removed and then OnEnd is called at the end and adding it back. haha.

 

Thank you again!

0 Kudos