I have a redistributable .MSM file from a third-party. I have downloaded 4
updated files for development to fix bugs. I now need to distribute these
updated files (DLLs) with my application. Knowing this company's history (I
won't name names) I doubt they will ever bother to reissue the MSM with the
updated files.....
So, I am trying to replace the current files with the new versions in the
MSM. I am happy to use Orca to up the versions/file sizes etc. But I do not
understand where the files"are" in the MSM. I can see that the "File" table
holds info about the files, but (I think) not the actual file. I got excited
about one post here talking about the "Binary" table holding a file he wanted
to distribute, and clicking on the "Data" column there looks good for
offering to read from file. But, there is only a single entry currently
there in the .MSM, and it's only 300K when I extract, so that can't be the
whole of the actual files.....
Where are the actual file contents? Can Orca read/write/package them? Or
is this whole exercise doomed in some way anyway?
The whole thing is only partially standardized.
The Binary table is normally the place to put
images, icons and various other resources.
But some companies get very creative with
MSIs: InstallShield embeds an entire MSI in
the Binary table that contains a number of I.S.
DLLs for their installer! And unfortunately there's
no single column in any table (at least not a
documented one) that lists the actual file names
of what's in the Binary table. But you can export
the table, which results in a folder containing
files with meaningless names. You can then
look at them in a hex editor to figure out what
you've got. (A BMP will start with "BM", an
EXE may have a Version file properties tab, etc.)
Now, I'm truly perplexed! Looking (Orca) at this "well known company's" MSM
file, there is no "Media" table at all. As I said, "Binary" contains just
one row which extracts to just 300K. Yet I know the MSM contains many
(large) files --- it's 25Mb big! I tried Orca's "Export [all] Tables", and
that only produced me 660K's worth of files..........
Looking through all the tables, I cannot see anything of interest. Where
else could the files/CAB be??????
Interesting. I don't have any MSMs here to look at, but
actually, according to the docs, the CAB can only
be one place in an MSM.
( You might want to download the SDK if you don't
already have it. The MSI.CHM help file is very extensive.)
In the help, under the section for the File table
in Merge Modules, it says this:
"Every file in the File table is stored inside of a cabinet
file in the .msi file. The name of this cabinet in a merge
module is always: MergeModule.CABinet"
It also says that the Media table is not required
in an MSM. The only required tables are these:
Component
Directory
FeatureComponents
File
ModuleSignature
ModuleComponents
So an MSM has to have a CAB, apparently, and it's always
the same name. So you should be able to just extract it
through the _Streams table using the name:
"MergeModule.CABinet". It makes sense that there'd be no
need to list it in the Media table if the name can't be changed
anyway.
(For future reference, anything listed in the Media table
of an MSI and preceded by a hash sign is internal. If there's no
hash sign it's a separate file. Ex: #data1.cab is in the MSI.
data1.cab is a separate file.)
I think you're maybe expecting more of knowledge of me about MSIs than I
have. All I have done is looked at MSM in Orca. So no programming.
To resume I think you're saying:
* The "File" table shows a list of the files, but you do not get at the
files from there
* There is a CAB file named "MergeModule.CABinet" somewhere "in" the MSM,
and it contains all the files and their contents
* There is *nowhere* in Orca where I can see or extract
"MergeModule.CABinet", not in any table, but it's in there
So the only way I can get at this file is "through the _Streams table",
which I take to mean I need to write a program using MSI SDK to open the MSM,
find the CAB file in this "table", extract it to disk from there, expand the
CAB, replace the files in it for which I have newer versions, remake the CAB,
and presumably write some more code to "put" the CAB back into a new version
of the MSM. Then fix up whatever information in, say, the File table which
showed the old file size/version.
Is that the gist? My dreams of using Orca to do the above are powder?
So may I ask you: is there a simple free tool I can use to achieve this?
Sounds like a lot of error-prone code for me otherwise. As I say, all I
would like to achieve is to replace a few files with newer versions, that's
it. How would you do this if asked?
Alternatively, a *possibility* would be for me to prodcue a "patch" thing
with just the new file versions in it. But reading that looked pretty
complex anyway (plus I think I had to produce the whole file content image
area to do that, which is half the problem), and then I'd have to understand
all the logic of where these files have to be installed, which is presumably
somehow in the existing MSM....
I would welcome your suggestion as to what to do next :-)
> To resume I think you're saying:
>
> * The "File" table shows a list of the files, but you do not get at the
> files from there
> * There is a CAB file named "MergeModule.CABinet" somewhere "in" the MSM,
> and it contains all the files and their contents
> * There is *nowhere* in Orca where I can see or extract
> "MergeModule.CABinet", not in any table, but it's in there
>
> So the only way I can get at this file is "through the _Streams table",
> which I take to mean I need to write a program using MSI SDK to open the
MSM,
> find the CAB file in this "table", extract it to disk from there, expand
the
> CAB, replace the files in it for which I have newer versions, remake the
CAB,
> and presumably write some more code to "put" the CAB back into a new
version
> of the MSM. Then fix up whatever information in, say, the File table
which
> showed the old file size/version.
>
> Is that the gist? My dreams of using Orca to do the above are powder?
That's the gist of it, yes. I haven't use Orca much.
I didn't realize that you couldn't write or extract the
CAB with that.
The basics, though, are as you're thinking: You'll need to
take the CAB out. The files in it will be named with nonsense
names. You'll need to cross-reference those with the File
table to figure out what's what. After you've redone the
CAB you'll need to put it back. (I've never done this but I
don't know of any reason it can't be done. Though you may need
to check through the MSM tables to make sure you've
updated any relevant file version entries connected with
your changes.)
>
> So may I ask you: is there a simple free tool I can use to achieve this?
> Sounds like a lot of error-prone code for me otherwise. As I say, all I
> would like to achieve is to replace a few files with newer versions,
that's
> it. How would you do this if asked?
>
I don't know if there's a tool that will do exactly what
you want. I can offer VBScript code to get you started.
You may not feel that ambitious, but if you do, here's a script
that should extract any MSM CAB and give you a general idea
of how to do the rest. Just copy the text below to Notepad,
save as a VBS file, and drop any MSM onto it. If it
works it will show a message displaying the path of
the extracted CAB file. (Watch for word wrap from email,)
__________ begin VBS code _______________
Dim Arg, WI, DB, s1, FSO, Pt1, MSMPath
Set FSO = CreateObject("Scripting.FileSystemObject")
Arg = WScript.Arguments(0)
If FSO.FileExists(Arg) = False Then
MsgBox "Drop an MSM file onto script.", 64
DropIt
End If
Pt1 = InStrRev(Arg, "\")
MSMPath = Left(Arg, (Pt1 - 1))
Set WI = CreateObject("WindowsInstaller.Installer")
Set DB = WI.OpenDatabase(Arg, 1)
s1 = GetTheCabOut(MSMPath, "MergeModule.CABinet")
MsgBox s1
DropIt
Sub DropIt()
Set FSO = Nothing
Set DB = Nothing
Set WI = Nothing
WScript.Quit
End Sub
Function GetTheCabOut(CabPath, sCabName)
Dim s, DLen, sFile, View, Rec
On Error Resume Next
Set View = DB.OpenView("SELECT `Name`,`Data` FROM _Streams WHERE
`Name`= '" & sCabName & "'")
View.execute
Set Rec = View.Fetch
If Rec is Nothing Then
Set View = Nothing
GetTheCabOut = ""
Exit Function
End If
DLen = Rec.datasize(2)
s = Rec.ReadStream(2, DLen, 2)
sFile = sCabName
If (UCase(Right(sFile, 3)) <> "CAB") Then sFile = sFile &
".cab"
Set TS = FSO.CreateTextFile(CabPath & "\" & sFile, True,
False)
TS.Write s
TS.Close
Set TS = Nothing
Set Rec = Nothing
Set View = Nothing
GetTheCabOut = CabPath & "\" & sFile
End Function
_________ end code ________________
Perform these steps to change the existing CAB
file in an MSM:
Save the script code below to Notepad.
Save as a file named ReplaceCAB.vbs.
Put the MSM into a folder with the new CAB file.
Name the new CAB "new.cab".
Drop the MSM onto ReplaceCAB.vbs.
MSM will now contain the new CAB file. You can
test it by droppong the MSM on the script from
the last post.
Script code for ReplaceCAB.vbs:
(Watch for word wrap again.)
___________________________________
Dim Arg, WI, DB, s1, FSO, Pt1, MSMPath
Set FSO = CreateObject("Scripting.FileSystemObject")
Arg = WScript.Arguments(0)
If FSO.FileExists(Arg) = False Then
MsgBox "Drop an MSM file onto script.", 64
DropIt
End If
Pt1 = InStrRev(Arg, "\")
MSMPath = Left(Arg, (Pt1 - 1))
'-- Replace CAB in MSM file. Put new CAB in same folder with MSM,
'-- drop MSM onto this script.
Set WI = CreateObject("WindowsInstaller.Installer")
Set DB = WI.OpenDatabase(Arg, 1)
ReplaceCAB MSMPath & "\new.cab", "MergeModule.CABinet"
DropIt
Sub DropIt()
Set FSO = Nothing
Set DB = Nothing
Set WI = Nothing
WScript.Quit
End Sub
Sub ReplaceCAB(CabPath, StreamName)
Dim s, DLen, sFile, View, Rec
Set View = DB.OpenView("SELECT `Name`,`Data` FROM _Streams")
View.execute
Set Rec = WI.CreateRecord(2)
Rec.StringData(1) = StreamName
Rec.SetStream 2, CabPath
View.Modify 3, Rec
DB.Commit
Set Rec = Nothing
Set View = Nothing
End Sub
________________________________
Thank you so much for your work.
I was able to use your scripts to extract the cabinet files, overwrite with
newer versions, and repackage. I then just found the files in the "File"
table in Orca and changed their version & size --- sounds correct??
Which all seemed to go well, till I tried to reinstall the rebuilt MSI with
the rebuilt MSM. Unfortunately, it now complains saying "Error writing to
file: <file>.dll. Verify that you have access to that directory." with just
a "Try Again" or "Cancel". The sad thing is the DLL file in question is
*not* one of the two I changed :-( (though it *is* one in the MSM). And I
reverified that I can still install using the original MSI/MSM.
So, unless you happen to know of something else I will have done wrong in
rebuilding the MSM, I shall have to put this down to an "unknown" in the guts
of Orca/MSI/MSM, and give up, because I suspect I will never find out what's
wrong. Which would be a sahme with all the hard work you have put in and
time I have spent, but I don't know what else to do.........
Oh well, what a fruitless exercise this has all turned out to be. I'll have
to hope that the supplier eventually updates their distributed MSMs, though I
have my doubts....
I just wanted to say thank you for all your efforts --- much appreciated.
>
> Oh well, what a fruitless exercise this has all turned out to be. I'll
have
> to hope that the supplier eventually updates their distributed MSMs,
though I
> have my doubts....
>
> I just wanted to say thank you for all your efforts --- much appreciated.
>
You're welcome. It's interesting to me, anyway.
One needs to know about MSIs these days to control
software installations.
If you don't have the W. I. SDK you should get it.
The help file is worthwhile. The whole system is
so complex and so non-intuitive that you ccan't
do much without msi.chm.
As for the CAB, I found this in msi.chm:
"The file sequence in the File table and in MergeModule.CABinet must be the
same. File sequence numbers are specified in the Sequence column of the File
table. "
There is a Sequence column in the File table. And you can
give CABARC a list via file:
cabarc n mycab.cab @filelist.txt
Maybe the file list gets numbered 1, 2, 3, ...etc.?
I haven't found info. about that. CABs are an odd
file format. I'm surprirsed that after all these years
MS doesn't seem to have come up with any sort
of GUI for them; only primitive and tedious command
line programs like MAKECAB and CABARC.
Fwiw WinZip can handle CABs, though I haven't experiemented enough to
see what happens with the file sequence.
Also fwiw, I've noticed that at least some CABs have the contents
sequenced with gaps e.g. 1,2,3,6,7,8 (where 4 & 5 are missing)
I have PowerArchiver and that can also handle CABS.
It tells me that all the files have to be added at once, I
suppose because they're strung together before
compression. But it doesn't say anything about numbering.
And I haven't found anything about numbering in the
CAB SDK, either. The MSI SDK notes the importance
of sequence but doesn't explain how to do it. ...Odd.
How are you finding the sequence that's missing numbers?
Does WinZip show that?
The actual numbers in the cabinet are I THINK irrelevant, its the ordering that is important,
so extracting the cabs contents and rebuiling in the correct order is probably the way to go.
Bye,
Dennis
Dennis Bareis [MVP] (dba...@KillSpam.gmail.com)
http://users.cyberone.com.au/dbareis/index.htm
Freeware Windows Installer creation tool (+ "ORCA automation"):
http://users.cyberone.com.au/dbareis/makemsi.htm
Sequencing works with MAKECAB.EXE (as I use it with my MAKEMSI tool)
and I assume other tools also by listing the files in the correct order. I would
also assume that adding files to a CAB would place them after all others.
I see. Thanks.
Wanted you to know, I have indeed got it all working OK. It looks like the
order of the files in the CAB does matter, to match with whatever "File"
table sequence numbers. At any rate, Orca verification no longer has errors
and the complaint on installing has gone away.
What I had to do was was use:
cabarc l file.cab > filelist.txt
This generated me a list (after some editing of the lines down to plain
filenames) for input back into:
cabarc n file.cab @filelist.txt
It does appear that "cabarc l" lists the files in the order they exist in
the cabinet.
I was able to replace the files after extraction and before replacement OK.
One thing that surprised me, and might interest you: the "File" table holds
each file's size & version. I am changing the file's size & version. To
start with, deliberately, I did *not* change the entries in the "File" table.
I assumed when I tried to install the .MSI it would complain that the file's
actual size/version did not match the info in the "File" table. A
fundamental check for an installer, and one I expected to verify that I had
changed the files. To my surprise, the install went through without
complaint. I find it rather worrying that this basic check does not appear
to be performed by W.I. ... ????
On Thu, 08 Jun 2006 00:08:07 GMT, "mayayana" <mayaXX...@mindXXspring.com> wrote:
> One wonders what the point of the
>file size value is if the installer's not going to bother
>checking it.
My guess its only used for file costing (working out how much disk space is required),
but you'd think it would check it at time of installation...