Groups | Blog | Home
all groups > dotnet sdk > april 2007 >

dotnet sdk : Embedding .NET CustomAction in Binary stream?


Tim Werth
4/4/2007 7:32:01 AM
I have written a .NET CustomAction and have added it to a merge module
project. After I compile the MSM and look at it in Orca, I notice the Binary
table has one row whose Name value is "InstallUtil". In the CustomAction
table, there are eight rows. There is a pair of rows for each action -
install, uninstall, rollback, and commit. The first row of each pair looks
like this:

Action = <guid>.install
Type = 1025 (that decimal)
Source = InstallUtil
Target = ManagedInstall

The other row looks like this:
Action = <same guid as above>.install.SetProperty
Type = 51 (formatted text)
Source = <same guid as above>.install
Target = /installtype=notransaction /action=install /LogFile= "[#<guid
referencing File.File value for my CA>]" "[VSDFxConfigFile]"

I understand the first row is actually a call to the InstallUtilLib.dll shim
and MangedInstall is the (only) entry point into that DLL. It appears the
second row sets up the CustomActionData to be passed to the ManagedInstall
exported function. From my testing I can see where ManagedInstall actually
kicks off InstallUtil.exe and pass the CustomActionData to my CA, which is a
physical file delivered to the disk.

Instead of leaving the CA on the target machine, I would like to embed my CA
into the Binary table and use the stream instead of a delivered file. Using
Orca, it is no problem for me to add my CA DLL into a stream in the Binary
table. My problem is how to I reference it in the CustomAction row that sets
up the parameters for the call to InstallUtilLib.ManagedInstall?
InstallUtil.exe appears to need to have a file on disk. How do I get my CA
out of the binary stream and into a physical file that InstallUtil.exe can
use? Or is there another way to skin this cat?

After this problem is solved, I have another downstream problem. In the
ModuleInstallExecuteSequence, the value in the Condition column for the 8
CustomAction rows is
$C__F4A03234F2024C5A925477584A7AB015.C23F5328603A4FD096CB1632F18AC7F2>2. The
C__F4A... is the component that is my CA. Once I embed the CA as a binary
stream, what do I put here in its place?

Thanks for any help you may have,
Phil Wilson
4/4/2007 1:38:28 PM
It doesn't seem me that it's worth it. You'd have to use the Msi APIs in a
custom action to stream the file from the Binary table to some "well known"
location like [TempFolder]. (Search on "msi stream from binary"). Then you'd
figure out the right value to pass into InstallUtilLib for the assembly
location (say [TempFolder]your.dll). If you used a managed code custom
action to do this streaming you'd be back again with a custom action using
InstallUtilLib referencing an assembly you'd need to install on disk. You
could use a C++ custom action instead to stream your file out of the Binary
table because a C++ custom action Dll can be marked Exclude in VS setups (VS
generates a custom action call to the Binary table). But then why not just
write the original custom action Dll call in C++ anyway, mark it Exclude,
and avoid all the complication? You're jumping through hoops to do
something that is unnecessary if you use a C++ Dll entrypoint. The bottom
line is that the implementation of managed code custom actions just works
this way, and the easiest way to have the stream from binary done for you is
to call a C++ entrypoint and mark the Dll as exclude.

Your last question, that's a condition, and it's nothing to do with where
the custom action lives. It just means it gets called when that component
gets installed.
--
Phil Wilson
[MVP Windows Installer]

[quoted text, click to view]

AddThis Social Bookmark Button