Home » MSI (Windows Installer) » Useful Adminstrative Scripts » Delete Empty Components

Delete Empty Components

Posted on by

Description:

This script will delete empty components from a Windows Installer.

Usage

CScript.exe {Script} {MSI}

Script

'set up log file
Dim fso : Set fso = CreateObject("Scripting.FileSystemObject")
Const ForReading = 1
Const ForWriting = 2
Const ForAppending = 8

'create a name/path for log file
Dim MSIPath : Set MSIPath = fso.GetFile(WScript.Arguments(0))  
Dim logFile : logFile = Left(MSIPath.Path, InStrRev(MSIPath.Path, ".") - 1) & ".log"

Dim objLogFile : Set objLogFile = fso.OpenTextFile(logFile, ForAppending, True)

WriteLog "Deleting Empty Components"
WriteLog "Processing: " & MSIPath.Name

'create 2 constants - one for when we want to just query the MSI (read) and one for when we want to make changes (write)

Const msiOpenDatabaseModeReadOnly = 0
Const msiOpenDatabaseModeTransact = 1

'create WindowsInstaller.Installer object
Dim oInstaller : Set oInstaller = CreateObject("WindowsInstaller.Installer")

'open the MSI (the first argument supplied to the vbscript)
Dim oDatabase : Set oDatabase = oInstaller.OpenDatabase(WScript.Arguments(0),msiOpenDatabaseModeTransact) 

Dim componentsView, componentsRec, tableView, tableRec, dataView, dataRec

Dim emptyComponent : emptyComponent = True
Dim tempComponent : tempComponent = ""

If oDatabase.TablePersistent("Component") = 1 Then

	Set componentsView = oDatabase.OpenView("Select `Component` From `Component` ORDER BY `Component`")
	componentsView.Execute
	Set componentsRec = componentsView.Fetch
	Do While Not componentsRec is Nothing

		tempComponent = componentsRec.StringData(1)
                emptyComponent = True

		'list the tables that have 'Component_' (foreign key) columns
		Set tableView = oDatabase.OpenView("SELECT `Table` FROM `_Columns` WHERE `Name`= 'Component_' AND `Table` <> 'FeatureComponents'") 
		tableView.Execute
		Set tableRec = tableView.Fetch
		Do While Not tableRec is Nothing
			
			Set dataView = oDatabase.OpenView("SELECT  `Component_` FROM `" & tableRec.StringData(1) & "`  WHERE `Component_`='" & tempComponent & "'")
			dataView.Execute
			If Not dataView.Fetch is Nothing Then 'this table has a some data belonging to some component
				'component contains data
				emptyComponent = False
				'skip component and move to next
				Exit Do
			End If

			Set tableRec = tableView.Fetch
		Loop

		If emptyComponent Then
			'delete the empty component
			oDatabase.OpenView("DELETE FROM `Component` WHERE `Component` = '" & tempComponent & "'").Execute

			oDatabase.OpenView("DELETE FROM `FeatureComponents` WHERE `Component_` = '" & tempComponent & "'").Execute

			WriteLog "Deleting empty component: " & tempComponent
		End If

		Set componentsRec = componentsView.Fetch
	Loop

	Set tableRec = Nothing
	Set tableView = Nothing
	Set componentsView = Nothing
	Set componentsRec = Nothing
	Set dataView = Nothing

End If	

oDatabase.Commit

objLogFile.Close
Set fso = Nothing
Set objLogFile = Nothing	
Set oDatabase = Nothing
Set oInstaller = Nothing

Sub WriteLog(LogMessage)

	WScript.echo Now() & ": " & LogMessage
    objLogFile.Writeline(Now() & ": " & LogMessage)

End Sub

 

12 thoughts on “Delete Empty Components

  1. Hi,

    i have tried using this script to remove empty component, but its not removing them, i am not getting any error it say just processing MSI.

    WriteLog “Deleting Empty Components”

    WriteLog “Processing: “ & MSIPath.Name

     

    i have updated the script with

    Dim Test : Set Test = dataView.Fetch ‘after line 51.

    Script is deleting some components with file along with empty components.

    Kindly Help.

    Many Thanks,

    Shashi

  2. Hmmm. I’ve just repositioned ’emptyComponent = True’. Try again – perhaps use WriteLog to debug the code. Let me know how you get on.

  3. If the MSI isn’t too big you can zip it and mail it to me. If it is big, strip out all the cabs/streams first…. Give me an example of a component that it is not removing.

  4. My Test MSI has some empty components i tried using the write log, the script is not going in to the below condition.

    If emptyComponent  Then
    WriteLog ” component name: ” & tempComponent
    WriteLog “Deleting empty component: ” & tempComponent
    End If

  5. If i add the below after line 51 in the script,

    Dim Test : Set Test = dataView.Fetch

    Script enters the loop :

    If emptyComponent  Then
    WriteLog ” component name: ” & tempComponent
    WriteLog “Deleting empty component: ” & tempComponent
    End If

    Log Output:

    9/27/2016 4:39:49 PM: Deleting Empty Components
    9/27/2016 4:39:49 PM: Processing: Test.msi
    9/27/2016 4:39:49 PM: component name: NewComponent2
    9/27/2016 4:39:49 PM: Deleting empty component: NewComponent2
    9/27/2016 4:39:49 PM: component name: NewComponent1
    9/27/2016 4:39:49 PM: Deleting empty component: NewComponent1
    9/27/2016 4:39:49 PM: component name: LendingBBLOracleConnect_old.dll
    9/27/2016 4:39:49 PM: Deleting empty component: LendingBBLOracleConnect_old.dll
    9/27/2016 4:39:49 PM: component name: OraOps10.dll
    9/27/2016 4:39:49 PM: Deleting empty component: OraOps10.dll
    9/27/2016 4:39:49 PM: component name: gacutil.exe
    9/27/2016 4:39:49 PM: Deleting empty component: gacutil.exe
    9/27/2016 4:39:49 PM: component name: LendingBBLOracleConnect_SELEX.dll
    9/27/2016 4:39:49 PM: Deleting empty component: LendingBBLOracleConnect_SELEX.dl

  6. Sorry, I can’t debug without seeing the MSI Tables. All I can suggest is that you use WriteLog to debug the SQL queries and the Loops/If statements…

  7. I have one query component having ini table entry I want move to different component   and then want delete that component ,

    For example ;

    A&B having two components

    A component having exe file

    B component having ini table entry

    Just I want to move ini file to A component

    Then I want delete B component

    Can you please add this point to delete component script

  8. Empty component having entry in create table, then that empty component will not be able to delete form the script, could please help

Comments have now been disabled. If you have a question to ask about this post please ask the community!