[wix-users] CustomAction does not seem to be called from the msi
Tom Brezinski
tom.brezinski at ViaviSolutions.com
Fri Feb 10 04:47:49 PST 2017
Yes a DLL will be created but it will usually be called <projectname>.dll. I've never seen a *.CA.dll for my C++ custom actions.
If you open the MSI in Orca and look at the Binary table you should see your DLL listed there by the ID you gave it.
Also on a side note I prefer to add my custom action DLL as a "reference" to the installer project. Then your SourceFile can be set to $(var.CustomActions.TargetPath) where "CustomActions" is the project name. Then you do not have to worry about release / debug or 32-bit vs 64-bit paths.
For example:
<Binary Id="NiwsActionsDLL" SourceFile="$(var.NiwsActions.TargetPath)" />
For logging just run "msiexec /i <msi-file> /l*v C:\log.txt"
Then look through your log file for the action name or anything you log using WcaLog in the C++.
I still suspect you have a scope problem though. Let me give you a complete example since you did not say that you tried my suggestion. Here is a complete installer all contained in one WXS file:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:difxapp="http://schemas.microsoft.com/wix/DifxAppExtension">
<Product Id="48C49ACE-90CF-4161-9C6E-9162115A54DD"
Name="WiX Patch Example Product"
Language="1033"
Version="1.0.0"
Manufacturer="Dynamo Corporation"
UpgradeCode="48C49ACE-90CF-4161-9C6E-9162115A54DD">
<Package Description="Installs a file that will be patched."
Comments="This Product does not install any executables"
InstallerVersion="400"
Compressed="yes" />
<Media Id="1" Cabinet="product.cab" EmbedCab="yes" />
<FeatureRef Id="SampleProductFeature"/>
</Product>
<Fragment>
<Feature Id="SampleProductFeature" Title="Sample Product Feature" Level="1">
<ComponentRef Id="SampleComponent" />
</Feature>
</Fragment>
<Fragment>
<DirectoryRef Id="SampleProductFolder">
<Component Id="SampleComponent" Guid="{C28843DA-EF08-41CC-BA75-D2B99D8A1983}" DiskId="1">
<File Id="driverDll" Source=".\$(var.Version)\TestDriver.dll" />
<File Id="driverCat" Source=".\$(var.Version)\TestDriver.cat" />
<File Id="driverInf" Source=".\$(var.Version)\TestDriver.inf" />
<difxapp:Driver PlugAndPlayPrompt="no" AddRemovePrograms="no" />
</Component>
</DirectoryRef>
</Fragment>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder" Name="PFiles">
<Directory Id="SampleProductFolder" Name="Patch Sample Directory">
</Directory>
</Directory>
</Directory>
</Fragment>
<Fragment>
<Binary Id="CAICRoot" SourceFile="..\CustomActions\CustomActions\bin\Release\CustomActions.dll"/>
<CustomAction Id="IronCADRootDirectory" BinaryKey="CAICRoot" DllEntry="GetICRootDir" Execute="firstSequence" HideTarget="no" />
<InstallExecuteSequence>
<Custom Action='IronCADRootDirectory' Before='InstallInitialize'/>
</InstallExecuteSequence>
</Fragment>
</Wix>
In this installer the CustomAction will never execute. Why? Because nothing in it is referenced in any way by the <Product>. Notice that the <Component> gets referenced by the <Feature> which gets referenced by the <Product>. For a <Fragment> to get included something must reference something in it. The solution I take to this problem is what I mentioned below. Add a <Directory> element to the fragment with the <CustomAction> and then in the <Fragment> that contains your <Feature> elements add a <DirectoryRef>. You do not have to install anything to that directory and thus it will never be created, but defining it and referencing it is enough to tie it back to the <Product> and get included in the installer.
-----Original Message-----
From: wix-users [mailto:wix-users-bounces at lists.wixtoolset.org] On Behalf Of Urban Olars
Sent: Thursday, February 09, 2017 12:15 AM
To: WiX Toolset Users Mailing List <wix-users at lists.wixtoolset.org>
Subject: Re: [wix-users] CustomAction does not seem to be called from the msi
There is no CustomActions.CA.dll being created. I am using Visual Studio
2010 and used the WIX template for C++ Custom Action when creating my project. Are you sure that there should be any *.CA.dll created for C++ custom actions? I am only guessing now but after Googling for this subject, it seems like C# custom action projects create a *.CA.dll but not C++ custom action projects. Could this be the case?
2017-02-07 16:16 GMT+01:00 Justin Cox <cox.justin.a at gmail.com>:
> You should be targeting the CustomsActions.CA.dll. Is it getting built
> in your bin\release folder? If not, you need to add it to you assembly
> and target that.
>
> On Tue, Feb 7, 2017, 4:15 AM Tom Brezinski <tom.brezinski at viavisolutions.
> com>
> wrote:
>
> > I have two ideas for you...
> >
> > First is your action might not be getting pulled in. For WiX to
> > include
> a
> > fragment it has to get tied back into the core <product> somehow. I
> > separate out my actions into their own WXS file / fragment which put
> > them out of scope.
> >
> > In order for them to be part of the install I have to put this at
> > the top of the fragment that has the actions:
> > <!-- Bogus folder so we can reference it to pull in this
> > fragment
> > -->
> > <DirectoryRef Id="INSTALLFOLDER">
> > <Directory Id="LegacyUpgradeActionsFolder" />
> > </DirectoryRef>
> >
> > And then inside the fragment that I specify my features I include a
> > Ref
> to
> > that folder:
> > <!-- Reference the bogus actions folder so that fragment gets pulled in.
> > -->
> > <DirectoryRef Id="LegacyUpgradeActionsFolder"/>
> >
> > Second idea is change the CustomAction to Execute="immediate" and
> schedule
> > it After="AppSearch" to make sure it happens really early. I am not
> > sure when the Condition element will be evaluated but I am sure it
> > is quite a bit before InstallInitialize. Also I am not sure when
> > firstSequence will schedule the action but I know that once the
> > install elevates it is difficult to use WcaSetProperty.
> >
> > If you do not have Orca download it. Opening your MSI and seeing
> > exactly what was built, what order actions were sequenced in, etc is
> > very
> valuable
> > for debugging.
> >
> > -----Original Message-----
> > From: wix-users [mailto:wix-users-bounces at lists.wixtoolset.org] On
> Behalf
> > Of Urban Olars
> > Sent: Tuesday, February 07, 2017 2:13 AM
> > To: WiX Toolset Users Mailing List <wix-users at lists.wixtoolset.org>
> > Subject: [wix-users] CustomAction does not seem to be called from
> > the msi
> >
> > Hi,
> >
> > I am trying to learn how to write custom actions in C++ and how to
> > use them in my msi installation project. Unfortunately with no luck
> > so far. I have looked at numerous examples I have found on internet
> > but still have not found out what I am doing wrong. I kindly ask for
> > input from someone
> on
> > this mailing list. Thank you in advance.
> >
> >
> > This is part of the code in my *.wxs file:
> > <Binary Id="CAICRoot"
> > SourceFile="..\CustomActions\CustomActions\bin\Release\
> CustomActions.dll"
> > /> <CustomAction Id="IronCADRootDirectory" BinaryKey="CAICRoot"
> > DllEntry="GetICRootDir" Execute="firstSequence" HideTarget="no" />
> >
> > <InstallExecuteSequence>
> > <Custom Action='IronCADRootDirectory' Before='InstallInitialize'/>
> > <RemoveExistingProducts Before="InstallInitialize"></
> RemoveExistingProducts>
> > </InstallExecuteSequence>
> >
> > <Condition Message="IronCAD root directory not found. Installation
> > aborting"> <![CDATA[ICROOTDIR]]> </Condition> ...
> > ...
> >
> >
> > This is part of the code in my custom action dll:
> > UINT __stdcall GetICRootDir(MSIHANDLE hInstall) { MessageBox(NULL ,
> _T("It
> > got called!") , _T("Title") , MB_OK); HRESULT hr = S_OK; UINT er =
> > ERROR_SUCCESS; // Initialize WiX Custom Action hr =
> WcaInitialize(hInstall,
> > "GetICRootDir"); ExitOnFailure(hr, "Failed to initialize");
> > WcaLog(LOGMSG_STANDARD, "Initialized.");
> >
> > if (hr == ERROR_SUCCESS)
> > {
> > LPWSTR lpwString = L"C:\\Program Files\\IronCAD"; // This is
> just
> > for testing. In reality I will look it up in the registry and cut
> > away part of the string hr = ::WcaSetProperty(TEXT("ICROOTDIR"),
> > lpwString); ExitOnFailure(hr, "Failed to set property"); } ...
> > ...
> >
> >
> > My msi project builds without errors but when I run the msi file, it
> > always stops at the condition message. Obviously, no property called
> > ICROOTDIR has been set. I added code for a message box in the custom
> > dll
> so
> > I should know that the function at least gets called but this
> > message box has never showed up so far. My assumption is therefore
> > that I have missed something fundamental so the custom dll never even gets called.
> >
> > I have added the entrypoint in the *.def file of my custom dll project:
> > LIBRARY "CustomActions"
> >
> > EXPORTS
> >
> > GetICRootDir
> >
> >
> > I haven't learnt yet how to log what is happening but I guess I will
> > have to unless someone of you can see right away what the problem is.
> >
> >
> >
> > Regards
> > Urban Olars
> >
> > ____________________________________________________________________
> > WiX Toolset Users Mailing List provided by FireGiant
> > http://www.firegiant.com/
> >
> > ____________________________________________________________________
> > WiX Toolset Users Mailing List provided by FireGiant
> > http://www.firegiant.com/
> >
>
> ____________________________________________________________________
> WiX Toolset Users Mailing List provided by FireGiant
> http://www.firegiant.com/
>
--
/Urban Olars
____________________________________________________________________
WiX Toolset Users Mailing List provided by FireGiant http://www.firegiant.com/
More information about the wix-users
mailing list