Updating WSI and MSI from external application

WISE_USER_1's picture

Having created skeleton WSI files (and related MSI files) for our project, I would like to programmatically update them from our build server, so that when we build new DLL and EXE files, these can be injected into the WSI and MSI files by the build script. I know this can be done with MSI files using the Microsoft APIs, but is there a programmatic interface for updating WSI files in this way? If so, could somebody please direct me to the documentation for the API.

Many thanks.

philbenson's picture

WSI files

have the same format as MSI files do. They just have "extra" tables inserted by wise, but have no file stream / injected files. If you have functions that work on MSI files, these should also work on WSI files. Try opening a WSI file with Orca, and you will see what I mean. As for compiling the WSI to a MSI file, you can use the (COM) Objects that are exposed by the Wise Package Studio Toolsets. Have a look in the (I think, been a while since I have looked, but there are examples for VB and C#) Help folder in the installation directory of Wise Packaging Studio.

Cheers
Phil

WISE_USER_1's picture

Writing binary data into MSI/WSI

Hi Phil,

Thanks for your answer. I hadn’t realised that WSI files used the same basic format as MSI – I had assumed they were proprietary. Thanks for the info.

When you say that they “have no file stream / injected files”, I assume that you mean WSI files don’t have any more embedded files (binary streams) than MSI files?

My understanding is that the files installed by our MSIs are contained in a cab file in the Cabs table of the MSI. So, I am assuming that to update an existing file in an existing MSI / WSI using the Microsoft API’s, all that needs to be done is to:

(1) Create a cab file containing the updated file
(2) Update the FileSize column for the contained file in the File table (as I am just updating an existing file, I don’t think any other column needs changing)
(3) Replace the binary data (using MsiRecordSetStream) for the cab file in the Cabs table

As I would be updating an existing file, I assume there is no need to update the Media table.

Alternatively, I assume that msidb could be used to replace the existing file?

Does that sound a reasonable approach, or am I missing something?

Thanks again.
 

philbenson's picture

I would go another way...

If the (source) file structure is static, (as also the number of resources to be installed), I would use the Wise automation interface to "recompile" the project file. It will automatically replace older files with newer ones, and create the MSI. You would only have to make sure that the GUIDS / versioning are updated to ensure that the resulting package will be an "Update" package. Alternativly you could also with automation create a patch (if required).

If you do go the hard way (i.e. directly editing the MSI file) then you will (eventually) get inconsistancies between your WSI project file, and the MSI file that may not be easy to identify. Also directly editing the cab file, and file table you would also need to ensure that hash values are consistant with files that contain no versioning (at that's just off the top of my head, I'd have to sit down and have a think to see if there is anything else that would nned to be taken into consideration)

Cheers
Phil

VBScab's picture

Too complicated!

If all you're doing is updating the file, you can just compile. Wise will pick up the updated file and write the appropriate changes to the relevant tables in the target MSI.

Don't know why 'x' happened? Want to know why 'y' happened? Use ProcMon and it will tell you.
Think about using http://www.google.com before posting.

philbenson's picture

Hi Ian,

that's what (I hope it was understood that way) I suggested. As I suspect it's part of an automated build process, using the COM interfaces of Wise is the easiest way (IMHO)

Cheers
Phil

WISE_USER_1's picture

Wise COM interfaces

Thanks Phil.

Could you direct me to the documentation for the Wise automation interface please. It sounds like that is the way to go.

Thanks again.

philbenson's picture

Hi, assuming that

you have installed Wise Package Studio (7.3) to the default location, you can find the files here -> "C:\Program Files\Altiris\Wise Package Studio\Technical Documentation"

Don't expect too much, as the examples are a bit (IMHO) iffy, but as a starting point they are OK, more for scripters and sharpers then "real" programmers ;-)

Cheers
Phil

WISE_USER_1's picture

Thanks

Thanks very much Phil. I've got them and will have a read.

Comment re. examples noted :-) Thankfully I tend to use examples just as a starting point, then go back to the reference to make sure I get the error handling and other detail correct.

Thanks again.

VBScab's picture

Iffy?!?!

How polite. LOL...

Don't know why 'x' happened? Want to know why 'y' happened? Use ProcMon and it will tell you.
Think about using http://www.google.com before posting.

JohanH's picture

Basically I do it like this

Basically I do it like this in vbscript:


Set objWfWI = CreateObject("Wfwi.Document" )
objWFWI.Open(YourwsiProject)
objWFWI.SetSilent      ' optional
' regenerate the Package Code (should always be done)
' Create a GUID
Set TypeLib = CreateObject("Scriptlet.TypeLib" ) : CheckErrorr
NewGUID = Left(TypeLib.Guid, len(TypeLib.Guid)-2)
Set TypeLib = Nothing
Set tbl = objWFWI.WTables("Summary")
Set row = tbl.WRows.Row("Package Code")
If (Nothing <> row) Then
    row("Value") = NewGUID
End If
' Do some other table updating stuff, e.g. update version, date and build number
' ....
objWFWI.Compile(wsiProject)
' objWFWI.Save(wsiProject)       '  to save the wsi only

EdT's picture

Automation Interface

You can use the automation interface to build an entire MSI if required, by editing the tables in your source WSI to update information about your files and then compiling to MSI. Do not try to create CAB files yourself unless you understand that the order of files in any cab exactly matches the order of file sequencing in the file table.

It's actually not that difficult to do, just tedious, as there is no "intelligence" in the automation interface, so if you add a component, for example, you will need to generate the GUID, add it to the FeatureComponents table, and make sure you fill in all the relevant columns.

Adding a file will require you to find a component to specify as the container for the file, and then you will need to find the next sequence number in the file table to allocate to your file. This usually means scanning through the existing table entries, so you will probably end up writing a few functions to do these repetitive tasks for you.

If your issue has been solved, please use the "Mark as Solution" link on the most relevant thread.