Hey guys,

I've just finished a package for Microsoft Dynamics NAV 2009. While the packaging was not too big a problem using silent install parameters and a config.xml, I do have one thing bothering me.

The total source of the package is about 1.8GB, but I'm really only installing a limited number of components. So what I would like to do is leave out those pieces (folders) of the source that don't get called by the installer for this particular type of install. Since it all gets cached by SCCM i'd like to avoid excess. I was wondering if any of you have ever developed a tool/procedure/script to 'monitor' these sources during install, to see which ones the installer calls upon.

I know I could use a trial and error approach, or dig into the installer more deeply, but I was hoping for a more universal solution, possibly reusable for future cases...

Thanks in advance,

PJ
0 Comments   [ + ] Show Comments

Comments

Please log in to comment

Rating comments in this legacy AppDeploy message board thread won't reorder them,
so that the conversation will remain readable.

Answers

0
Hi, Pieter.

An interesting one...

In your shoes, I'd be looking at using the scripts in the SDK to match features to components then looking up the source using the WI object model.
Answered 09/23/2011 by: VBScab
Red Belt

Please log in to comment
0
Hey Ian,

been doing some research on this (it's friday afternoon, shoot me) and I've stumbled upon sysinternal's handle.exe
This might be a nice starting point for a little programming/scripting project, I'll keep you guys posted.

Any further suggestions are still most welcome.

PJ
Answered 09/23/2011 by: pjgeutjens
Red Belt

Please log in to comment
0
your a pretty competent scriptor so I imagine whipping a script that reverse engineers the file table / cab files etc shouldn't be too hard.

Although as this is dynamix (MS) I expect they are using the msiEmbeddedUi api to launch multiple msi's which would make it very difficult to trace across multiple msi's. Perhaps you could work out the msi's from the config.xml then iterate through each msi.

Actually on second thoughts you would have to work out the features selected states etc, then trawl the components / files then cabs of those selected files. So it would be pretty interesting. i have something around that does all the session state feature stuff as I was bored one day.

give me a shout if you need it.
Answered 09/23/2011 by: jmcfadyen
Fifth Degree Black Belt

Please log in to comment
0
Just did a quick vbscript to fetch the files from specified components, maybe it can help on the way ;)


Const msiOpenDatabaseModeReadOnly = 0
Const msiUILevelProgressOnly = 64

Dim oSession, COMPONENT_LIST

filePath = WScript.Arguments(0)
Set COMPONENT_LIST = CreateObject("Scripting.Dictionary")

'// components to fetch files from
COMPONENT_LIST.Add "Component1", ""
COMPONENT_LIST.Add "Component2", ""
COMPONENT_LIST.Add "Component3", ""

Call GetSession(filePath, oSession)

Call GetFileList(filePath, COMPONENT_LIST, oSession)
ListFilesByComponent COMPONENT_LIST

Sub ListFilesByComponent(ByVal oComponentList)
Dim component, fileList, filePath

For Each component In oComponentList
WScript.Echo "### Component: " & component

Set fileList = oComponentList.Item(component)
For Each filePath In fileList
WScript.Echo filePath
Next
Next
End Sub

Function GetFileList(ByVal sMsiFilePath, ByRef oComponentList, ByVal oSession)
Dim component, fileList

For Each component In oComponentList
Set fileList = GetFileListByComponent(sMsiFilePath, oSession, component)
Set oComponentList.Item(component) = fileList
Next
End Function

Function GetFileListByComponent(ByVal sMsiFilePath, ByVal oSession, ByVal sComponent)
Dim fileList, fileName, folderPath, filePath
Dim oInstaller, oDatabase, oView, oRecord

Set fileList = CreateObject("Scripting.Dictionary")

Set oDatabase = oInstaller.OpenDatabase(sMsiFilePath, msiOpenDatabaseModeReadOnly)

Set oView = oDatabase.OpenView("SELECT * FROM `Component` WHERE `Component` = '" & sComponent & "'")
oView.Execute
Set oRecord = oView.Fetch
folderPath = oSession.Property(oRecord.StringData(3))
oView.Close

Set oView = oDatabase.OpenView("SELECT * FROM File WHERE `_Component` = '" & sComponent & "'")
oView.Execute

Set oRecord = oView.Fetch
Do While Not (oRecord Is Nothing)
fileName = oRecord.StringData(3)
If InStr(1, fileName, "|") <> 0 Then fileName = Split(fileName, "|", 2)(1) '// get long filename if specified

filePath = folderPath & "\" & fileName
fileList.Add filePath, sComponent

Set oRecord = oView.Fetch
Loop

Set GetFileListByComponent = fileList

Set oRecord = Nothing
Set oView = Nothing
Set oDatabase = Nothing
End Function

'// executes all actions until (before) InstallValidate
Function GetSession(ByVal sMsiFilePath, ByRef oSession)
Dim oInstaller, oDatabase, oView, oRecord

Set oInstaller = CreateObject("WindowsInstaller.Installer")
oInstaller.UILevel = msiUILevelProgressOnly

Set oDatabase = oInstaller.OpenDatabase(sMsiFilePath, msiOpenDatabaseModeReadOnly)
Set oSession = oInstaller.OpenPackage(sMsiFilePath, 0)

Set oView = oDatabase.OpenView("SELECT * FROM `InstallExecuteSequence` Order By `Sequence`")
Set oRecord = oView.Fetch
Do While Not (oRecord Is Nothing)
oSession.DoAction oRecord.StringData(1)

If (UCase(oRecord.StringData(1)) = UCase("InstallValidate")) Then Exit Do
Set oRecord = oView.Fetch
Loop
oView.Close

Set oRecord = Nothing
Set oView = Nothing
Set oDatabase = Nothing
End Function

Answered 09/26/2011 by: AngelD
Red Belt

Please log in to comment
Answer this question or Comment on this question for clarity