Your strategic advantage starts here

Delete Empty Components

Delete Empty Components

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

 

Related Posts
12 Comments
shashi patil

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

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

shashi patil

Still no luck 🙁

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.

shashi patil

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

shashi patil

its just a simple MSI i have created with some random .dll, .exe and empty component

shashi patil

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

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…

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

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

but it’s not working for my logic

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

Leave a Reply
Give us a call

Available from 9am to 8pm, Monday to Friday.

Send us a message

Send your message any time you want.

Our usual reply time: 1 Business day
Give us a call

Available from 9am to 8pm, Monday to Friday.

Send us a message

Send your message any time you want.

Our usual reply time: 1 Business day