Registering SharpShell extension using SRM via WIX installer - wix

Firstly I should clarify that I am a novice and have been struggling to understand the WIX formatting, but by cobbling together examples found on-line, I now have the files installing fine so I next need to register my DLL.
I used the example here as a starting point: How to deploy a SharpShell-based shell extension via WiX? but it seems that the SharpShell tool srm.exe may not be getting called at installation.
If I manually call srm.exe as follows, it works as hoped i.e. the DLL is registered and my shell extension works.
srm install MyExtension.dll -codebase
I can also see that the registration has been successful via the Server Manager application that comes with SharpShell.
I can also manually uninstall with the following - not that this is particularly relevant to my problem but it at least confirms that the manual methods work:
srm uninstall MyExtension.dll
Here is a fragment of my WXS file. When I run the resultant MSI, the files are installed but the DLL is not being registered; confirmed via SharpShell's Server Manager. Where am I going wrong?
</Component>
<Component Id="SRMexe" Guid="C17BB61F-6471-46F9-AA87-2D14D2456632">
<File Id='srm' Name='srm.exe' DiskId='1' Source='..\MyExtension\packages\SharpShellTools.2.2.0.0\lib\srm.exe' KeyPath='yes'>
</File>
</Component>
<!-- TODO: Insert files, registry keys, and other resources here. -->
<!-- </Component> -->
</ComponentGroup>
</Fragment>
<Fragment>
<CustomAction Id="InstallShell" FileKey="srm"
ExeCommand='install "[INSTALLFOLDER]\MyExtension.dll" -codebase'
Execute="deferred" Return="check" Impersonate="no" />
<CustomAction Id="UninstallShell" FileKey="srm"
ExeCommand='uninstall "[INSTALLFOLDER]\MyExtension.dll"'
Execute="deferred" Return="check" Impersonate="no" />
<InstallExecuteSequence>
<Custom Action="InstallShell"
After="InstallFiles">
NOT Installed
</Custom>
<Custom Action="UninstallShell"
Before="RemoveFiles">
(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")
</Custom>
</InstallExecuteSequence>
</Fragment>

It doesn't look like you have any references to the Fragment with the CustomAction definitions so they are not linked into your final output MSI.
Add a CustomActionRef from your Product element to create the reference.

Related

How to prevent json modification while wix msi upgrading

I am new to wix msi .I am using Wix to create msi for my window service .While installing msi, a json file will be created in installation folder with application details(using .net core). This file will be modified (recreating) while upgrading msi .I want to prevent json being modified on each msi upgrade.
I have tried couple of methods. But didn't get desired result.
1.Using custom action-
<Property Id="C_TEMP" Value="C:\Temp" />
<Property Id="ROBOCOPY_EXE">robocopy.exe</Property>
<CustomAction Id="CopyToTemp" Property="ROBOCOPY_EXE" Return="ignore" ExeCommand='"[INSTALLDIR]\Configuration" "[C_TEMP]\ServerSettings" AgentDetails.json' />
<CustomAction Id="CopyFromTemp" Property="ROBOCOPY_EXE" Return="ignore" ExeCommand='"[C_TEMP]\ServerSettings" "[INSTALLDIR]\Configuration" AgentDetails.json /MOVE /IS' />
<InstallExecuteSequence>
<Custom Action="CopyToTemp" Before="InstallInitialize">Installed AND (NOT REMOVE="ALL" OR UPGRADINGPRODUCTCODE)</Custom>
</InstallExecuteSequence>
using component
<Component Id="myconfig" NeverOverwrite="yes" Permanent="yes" >
<File Id="AgentDetails.json" Name="AgentDetails.json" KeyPath="yes" Source="$(var.BasePath)\AgentDetails.json" />
</Component>

In my Windows WiX Installer my Custom Actions don't run

I want to have the installer/uninstaller remove a folder that contains content generated by the application at run time. I figured a Custom Action would be the way to go.
We are using WiX 3.6.
(I want it in the installer sequence for a specific reason that is not important to this question.)
Here is my CustomAction definitions in the xml:
<Binary Id="CustomActionLib" SourceFile="$(var.CustomActionLibrary.TargetDir)$(var.CustomActionLibrary.TargetName).CA.dll" />
<CustomAction Id="DeleteLocalizedCA" Impersonate="yes" BinaryKey="CustomActionLib" DllEntry="DeleteLocalized" Return="check" />
<CustomAction Id="DeleteResourcesCA" Impersonate="yes" BinaryKey="CustomActionLib" DllEntry="DeleteResources" Return="check" />
Here are my references to them:
<InstallExecuteSequence>
<Custom Action="DeleteLocalizedCA" Before="InstallFiles"/>
<FindRelatedProducts Before="LaunchConditions" />
<RemoveExistingProducts After="InstallFinalize" />
<RemoveShortcuts>Installed AND NOT UPGRADINGPRODUCTCODE</RemoveShortcuts>
</InstallExecuteSequence>
<InstallUISequence>
<Custom Action="DeleteLocalizedCA" Before="InstallFiles"/>
<FindRelatedProducts Before="LaunchConditions" />
</InstallUISequence>
I added the CustomActionLibrary project to the solution and added a reference to it from the installer project but it never runs, I never see it in the logs, nothing!
And thus my question, Why Don't my WiX Custom Actions Run?
After several hours of googling and reading (Blog posts, documentation, Stackoverflow, etc.) and testing I finally found a solution that none of my reading pointed to.
I had to put an InstallExecuteSequence to contain my references in a fragment that contained a ComponentGroup:
<Fragment>
<InstallExecuteSequence>
<Custom Action="DeleteLocalizedCA" Before="InstallFiles">NOT Installed</Custom>
</InstallExecuteSequence>
<ComponentGroup Id='StringsComponents'>
...
</ComponentGroup>
</Fragment>
The Fragment that I had previously put the CustomAction reference in only had steps but no Component or ComponentGroup so apparently doesn't do anything. (I am not the original author of the installer, just taking over for a co-worker who wasn't able to help me on this).
Hopefully this helps others who are struggling with the same issue.

Custom Action for Feature in WIX

I am trying to execute an EXE file through my installation and this file should be installed if the related feature will be installed in the feature tree.
I have two questions :
1-How to relate the Custom Action to this feature."The condition"
2- How I can include this exe file in the generated file. "This EXE File is a SQL Installation which I already made in WIX BOOTSTRAPPER "
http://apprize.info/web/wix/13.html
and my code is
<Feature Id="SubFeature1" Title="SQL Installation" Level="1" >
<ComponentRef Id="SubComponent1"/>
</Feature>
<Feature Id="SubFeature2" Title="Second Subfeature" Level="1" >
<ComponentRef Id="SubComponent2"/>
<!-- <Condition Level="0">IISMAJORVERSION=""</Condition> -->
</Feature>
</Feature>
<CustomAction Id="CreateSQLINSTALLER" Directory="BMSS4_Installer"
Execute= "deferred" Impersonate="no" Return="ignore"
ExeCommand="[BMSS4_Installer]Sql_Installation_Test1.exe -install" />
<InstallExecuteSequence>
<Custom Action="CreateSQLINSTALLER" Before="InstallFinalize"><![CDATA[(&SubFeature1)]]></Custom>
</InstallExecuteSequence>
the Sql_Installation_Test1.exe is included in the main folder so BMSS4_Installer..
But is it right to use it direclty like that in Directory tag om CustomAction !!
Feature conditions are documented here:
https://msdn.microsoft.com/en-us/library/aa368012(v=vs.85).aspx
in the action state of the feature. Basically you use a condition such as:
&featurename=3
where 3 is INSTALLSTATE_LOCAL, as there in the documentation. There are limits on where the condition can be used, the main one being after CostFinalize.
It's not clear if you are installing some version of SQL itself, but that would have its own install and wouldn't need repackaging, and it would be a prerequisite installed with Burn, for example. If it's a separate MSI setup of yours, again a Burn package would probably be the best way to install it and your other MSI.

How to use selfextract files in a wix install

I am really new using WIX, my only experience to build a complete install was with INNO, and WIX has been decided the way to go for an MSI
The installation includes a bunch of examples and templates, 427 files, which seems crazy to enumerate even with an utility like HEAT.EXE
So we went for a self-extracting utility. WIX install includes this custom utility and the compressed cabinet file, and then that extracts files and folders via custom action.
Problem is when we try to delete the compressed file and the extractor utility. I haven't found the way to delete them after the extraction takes place. RemoveFile seems to not work, and deleting the file within the extraction utility fires the self-healing mechanism in every run of the application.
Leaving the files in the install is dangerous, it is 200MB and it would reset all the installed examples if user runs the self-extraction utility by accident.
If it is of use, the WIX snippet in charge of this is like that:
<Fragment>
<ComponentGroup Id="App_Files">
<Component Id="cmp_Files_Dat" Directory="INSTALLCOMMONFOLDER" Guid="{8BFED6C2-4D4F-48BB-xxxx-C171F624C90B}">
<File Id="fil_Files_Dat" Source="appfiles\files.dat" />
<RemoveFile Id="rem_Files_Dat" Name="files.dat" On="install" />
</Component>
<Component Id="cmp_UnpackFiles_exe" Directory="INSTALLCOMMONFOLDER" Guid="{5722B5E0-C6E8-4C71-yyyy-61EC0ACA0D72}">
<File Id="fil_UnpackFiles_exe" Source="appfiles\UnPackFiles.exe" Checksum="yes" />
<RemoveFile Id="rem_UnpackFiles_exe" Name="UnPackFiles.exe" On="install" />
</Component>
</ComponentGroup>
<CustomAction Id="action_UnPackFiles" FileKey="fil_UnpackFiles_exe" ExeCommand="[INSTALLCOMMONFOLDER]" Execute="commit" Return="check" Impersonate="no" />
<InstallExecuteSequence>
<Custom Action="action_UnPackFiles" After="InstallFiles" > NOT (REMOVE="ALL") </Custom>
</InstallExecuteSequence>
</Fragment>
The net result of the code above leaves the files, does not remove them.
Thanks in advance
Josep

WIX Uninstall Custom Action Error Code 2753

I'm having problems with a WIX CustomAction that I'd like to run when a user uninstalls an application.
Here's my XML
http://schemas.microsoft.com/wix/2006/wi'>
<Package Description='pak' InstallerVersion='200' Compressed='yes' />
<Media Id='1' Cabinet='setup.cab' EmbedCab='yes' />
<Property Id='ARPSYSTEMCOMPONENT'>1</Property>
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id="TempFolder">
<Directory Id="INSTALLLOCATION" Name="~_tmpdir">
<Component Id='MyComponent' DiskId='1' Guid=''>
<File Id="File0" Name="Runtime.exe" Source="Runtime.exe" />
</Component>
</Directory>
</Directory>
</Directory>
<Feature Id='InstallFeature' Title='Install Feature' Level='1'>
<ComponentRef Id='MyComponent' />
</Feature>
<CustomAction Id="RunInstall" Return="ignore" Execute="deferred" FileKey="File0" ExeCommand="Runtime.exe" HideTarget="no" Impersonate="no" />
<CustomAction Id="RunUninstall" Return="ignore" Execute="deferred" FileKey="File0" ExeCommand="Runtime.exe" HideTarget="no" Impersonate="no" />
<InstallExecuteSequence>
<Custom Action="RunInstall" Before="InstallFinalize">NOT REMOVE~="ALL"</Custom>
<Custom Action="RunUninstall" Before="InstallFinalize">REMOVE~="ALL"</Custom>
</InstallExecuteSequence>
The Runtime.exe launches as expected when installing the application but when I uninstall I get an error "The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2753".
Looking at the event viewer sheds a little more light on the problem, it contains the following "The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2753. The arguments are: File0, , ".
So, it seems like it can't find Runtime.exe but I'm not sure why. The file is bundled into the MSI and it runs on install but I can't work out why it doesn't run on uninstall.
Many thanks
You should sequence the uninstall custom action earlier. "Before InstallFinalize" is very late, and almost certainly results in attempting to run the program after RemoveFiles has deleted it, hence the error. Look at the InstallExecuteSequence in your MSI file and see where RemoveFiles is relative to your CA and InstallFinalize. You may need to be before StopServices and other actions that remove registry values, depending on how much of the installed product your code needs. Or run it from the Binary table (beware of dependencies) if it really needs to be literally just before the uninstall completes.