We have a growing list of files that are frequently updated through a filelist. We have a utility that retrieves the files from the filelist from different locations and dumps them into one folder and its subfolders.
Every time the filelist changes, I have to make sure that I add new files by using the InstallShield GUI. How can I automate this process?
This is a ready-only archive of the InstallSite Forum. You cannot post any new content here. / Dies ist ein Archiv des InstallSite Forums. Hier können keine neuen Beiträge veröffentlicht werden.
Can I add files programmatically?
Started by
shahedC
, Nov 22 2004 15:17
3 replies to this topic
Posted 22 November 2004 - 15:22
Some more info/questions:
1) I can use Dynamic Folders, so that I would only have to link to each folder and not each specific file.
But there are two problems:
(a.) my folders also contain other files that I do not want to include in the installation. So I can't really use Dynamic Folders in this scenario. But let's say I remove the unwanted files from my Dyanamic Folders. That brings me to:
(b.) I've heard that Dynamic Folders prevent me from assigning key files to each folder. This will apparently prevent me from building Upgrade versions of my installation. (Is this true?)
2) Does InstallShield have an API that lets me alter the ISM file programmatically, and add files to it?
1) I can use Dynamic Folders, so that I would only have to link to each folder and not each specific file.
But there are two problems:
(a.) my folders also contain other files that I do not want to include in the installation. So I can't really use Dynamic Folders in this scenario. But let's say I remove the unwanted files from my Dyanamic Folders. That brings me to:
(b.) I've heard that Dynamic Folders prevent me from assigning key files to each folder. This will apparently prevent me from building Upgrade versions of my installation. (Is this true?)
2) Does InstallShield have an API that lets me alter the ISM file programmatically, and add files to it?
Edited by shahedC, 22 November 2004 - 15:23.
Posted 22 November 2004 - 15:42
Please, see InstallShield documentation > Advanced Features > Automation Interface. It provide COM interface to manage InstallShield project.
With AddFile method in particular you can perform this task.
You need to be familiar with Features, components, properties and other MSI database parts.
Hope this helps.
With AddFile method in particular you can perform this task.
You need to be familiar with Features, components, properties and other MSI database parts.
Hope this helps.
Posted 22 November 2004 - 16:32
We have a similar problem to yours. Although I don't add files to my components, I do have lots and lots of data files that are organized into components. Since there is not one single datafile in the component that always changes if any of the others do (ie no good candidate for a key file), I create one using automation. In each of the components that has datafiles, I add a component called <componenetname>key.xml, and set that to the key file for the component. Then I use the automation interface to rebuild the keyfile.
The keyfile looks like this (abbreviated to save space):
<Component name="DataSection1">
<File Name="_2020.Dat" Modified="06/11/2004 1:15:53 PM"/>
<File Name="_2001.Dat" Modified="06/16/2004 12:29:03 PM"/>
<File Name="_2002.Dat" Modified="06/16/2004 12:29:03 PM"/>
<File Name="_2003.Dat" Modified="06/16/2004 12:29:03 PM"/>
<File Name="_2004.Dat" Modified="06/16/2004 12:29:03 PM"/>
<File Name="_2005.Dat" Modified="06/16/2004 12:29:03 PM"/>
<File Name="_2006.Dat" Modified="06/02/2004 2:33:03 PM"/>
<File Name="_2007.Dat" Modified="06/02/2004 2:33:03 PM"/>
<File Name="_2008.Dat" Modified="06/02/2004 2:33:03 PM"/>
<File Name="_2009.Dat" Modified="06/02/2004 2:33:03 PM"/>
<File Name="_2010.Dat" Modified="06/02/2004 2:33:03 PM"/>
<File Name="_2011.Dat" Modified="06/02/2004 2:33:03 PM"/>
<File Name="_2012.Dat" Modified="06/11/2004 1:15:48 PM"/>
<File Name="_2013.Dat" Modified="06/11/2004 1:15:48 PM"/>
<File Name="_2021.Dat" Modified="06/11/2004 1:15:53 PM"/>
</Component>
When I build, I compare the file dates against the keyfile dates. If the file dates are newer, the keyfile is updated.
Here is the code (and an example of using the automation interface)
The keyfile looks like this (abbreviated to save space):
<Component name="DataSection1">
<File Name="_2020.Dat" Modified="06/11/2004 1:15:53 PM"/>
<File Name="_2001.Dat" Modified="06/16/2004 12:29:03 PM"/>
<File Name="_2002.Dat" Modified="06/16/2004 12:29:03 PM"/>
<File Name="_2003.Dat" Modified="06/16/2004 12:29:03 PM"/>
<File Name="_2004.Dat" Modified="06/16/2004 12:29:03 PM"/>
<File Name="_2005.Dat" Modified="06/16/2004 12:29:03 PM"/>
<File Name="_2006.Dat" Modified="06/02/2004 2:33:03 PM"/>
<File Name="_2007.Dat" Modified="06/02/2004 2:33:03 PM"/>
<File Name="_2008.Dat" Modified="06/02/2004 2:33:03 PM"/>
<File Name="_2009.Dat" Modified="06/02/2004 2:33:03 PM"/>
<File Name="_2010.Dat" Modified="06/02/2004 2:33:03 PM"/>
<File Name="_2011.Dat" Modified="06/02/2004 2:33:03 PM"/>
<File Name="_2012.Dat" Modified="06/11/2004 1:15:48 PM"/>
<File Name="_2013.Dat" Modified="06/11/2004 1:15:48 PM"/>
<File Name="_2021.Dat" Modified="06/11/2004 1:15:53 PM"/>
</Component>
When I build, I compare the file dates against the keyfile dates. If the file dates are newer, the keyfile is updated.
Here is the code (and an example of using the automation interface)
CODE |
'this is the project you will build Dim mstrProject: mstrProject = "D:\MyProject.ism main Sub main() Dim lobjProj: Set lobjProj = CreateObject("ISWiAutomation.ISWiProject") lobjProj.OpenProject mstrProject Dim lblnChanges Dim lobjKeyXML Dim lobjComp For Each lobjComp In lobjProj.ISWiComponents 'reset Key values lblnChanges = False Set lobjKeyXML = Nothing 'only process desired components, those with a keypath = <omponentname>key.xml If (strComp(Right(lobjComp.Keypath, 7), "key.XML", 1) = 0) Then 'Get the keyfile for the component Set lobjKeyXML = GetComponentKeyFile(lobjComp.ISWiFiles(lobjComp.Keypath).FullPath, lobjComp.Name) If lobjKeyXML is Nothing then msgbox "could not get Component Key XML" Exit Sub End If 'process the component files Dim lobjFile, lobjFileNode For Each lobjFile In lobjComp.ISWiFiles if strComp(Right(lobjFile.name, 3), "XML", 1) <> 0 Then 'get the file node for the current file Set lobjFileNode = GetFileNode(lobjKeyXML, lobjFile.Name) 'find out if it has been updated If FileChanged(lobjFileNode, lobjFile.FullPath) then lblnChanges = True End If End If Next 'if the component has updated files, update the key file If lblnChanges Then lobjKeyXML.Save lobjComp.ISWiFiles(lobjComp.Keypath).FullPath End If End If Next lobjProj.CloseProject End Sub Function GetComponentKeyFile(strKeyPath, strName) 'verify the component file exists Dim FSO: Set FSO = CreateObject("Scripting.FileSystemObject") If not FSO.FileExists(strKeyPath) Then msgbox "cannot find file " & strKeyPath End If Dim lobjKeyXml: Set lobjKeyXML = CreateObject("Msxml2.FreeThreadedDOMDocument.4.0") lobjKeyXML.load(strKeyPath) If err.number <> 0 or len(lobjKeyXML.xml) = 0Then lobjKeyXML.loadxml("<Component name=""" & strName & """ />") End If 'Handle error here Set GetComponentKeyFile = lobjKeyXML End Function Function GetFileNode(aobjKeyXML, astrFileName) Dim lobjFileNodes, lobjFileNode, lobjResultNode Set lobjFileNodes = aobjKeyXML.getElementsByTagName("File") Set lobjResultNode = nothing For Each lobjFileNode In lobjFileNodes If lobjFileNode.Attributes.getNamedItem("Name").Text = astrFileName Then Set lobjResultNode = lobjFileNode Exit For End If Next If lobjResultNode is Nothing Then Set lobjResultNode = aobjKeyXML.createElement("File") Dim lobjNameAttr: Set lobjNameAttr = aobjKeyXML.createAttribute("Name") lobjNameAttr.Value = astrFileName lobjResultNode.Attributes.setNamedItem lobjNameAttr Dim lobjParent: Set lobjParent = aobjKeyXML.documentElement lobjParent.appendChild lobjResultNode End If Set GetFileNode = lobjResultNode End Function '****************************************************************************** ' Function FileChanged - updates the node if it changed ' ' parms: ' lobjNode - an XML node representing the last know info on the file ' lstrFile - the path to the current file ' ' returns: boolean indicating if the file has changed Function FileChanged(lobjNode, lstrFile) Dim lblnChanged: lblnChanged = False Dim FSO: Set FSO = CreateObject("Scripting.FileSystemObject") Dim lobjFile: Set lobjFile = FSO.GetFile(lstrFile) Dim lobjModified Set lobjModified = lobjNode.Attributes.getNamedItem("Modified") If Not lobjModified is nothing Then If DateDiff("d", lobjFile.DateLastModified, lobjNode.Attributes.getNamedItem("Modified").Text) > 0 then lobjNode.Attributes.getNamedItem("Modified").Text = lobjFile.DateLastModified lblnChanged = True End If Else Dim lobjModAttr: Set lobjModAttr = lobjNode.ownerDocument.createAttribute("Modified") lobjModAttr.Value = lobjFile.DateLastModified lobjNode.Attributes.setNamedItem lobjModAttr lblnChanged = True End If FileChanged = lblnChanged End Function |