Wix installer unexpected error - wix

I am getting below error while running wix installer to install windows service:
The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2343. The arguments are: , ,
MSI (s) (20:E0) [12:15:16:924]: Product: ABC.NS.Scheduler.Deployment.SCHEDULER -- The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2343. The arguments are: ,
Below is the are the logs:
=== Logging started: 5/18/2015 12:15:16 ===
Action start 12:15:16: INSTALL.
Action start 12:15:16: FindRelatedProducts.
Action ended 12:15:16: FindRelatedProducts. Return value 1.
Action start 12:15:16: AppSearch.
Action ended 12:15:16: AppSearch. Return value 1.
Action start 12:15:16: LaunchConditions.
Action ended 12:15:16: LaunchConditions. Return value 1.
Action start 12:15:16: ValidateProductID.
Action ended 12:15:16: ValidateProductID. Return value 1.
Action start 12:15:16: CostInitialize.
Action ended 12:15:16: CostInitialize. Return value 1.
Action start 12:15:16: FileCost.
Action ended 12:15:16: FileCost. Return value 1.
Action start 12:15:16: CostFinalize.
Action ended 12:15:16: CostFinalize. Return value 1.
Action start 12:15:16: SetInstallLocationRootDirectory.
DEBUG: Error 2343: Specified path is empty.
The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2343. The arguments are: , ,
MSI (s) (20:E0) [12:15:16:924]: Product: ABC.NS.Scheduler.Deployment.SCHEDULER -- The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2343. The arguments are: , ,
Action ended 12:15:16: SetInstallLocationRootDirectory. Return value 3.
Action ended 12:15:16: INSTALL. Return value 3.
Property(S): UpgradeCode = {144D75A6-0CCB-4AAC-8547-C904DF2FAE7D}
Property(S): NETFRAMEWORK45 = #379893
CODE:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<?include Includes\Dependencies.wxi?>
<Product Id="{51669456-A144-4A44-BE32-958BB4E8CD3D}"
Name="ABC.NS.Scheduler.Deployment.SCHEDULER"
Language="1033"
Version="$(var.ProductVersion)"
Manufacturer="ABC"
UpgradeCode="144d75a6-0ccb-4aac-8547-c904df2fae7d">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="!(loc.LaterVersionAlreadyInstalled)" />
<PropertyRef Id="NETFRAMEWORK45"/>
<Condition Message="!(loc.DotNetFrameworkIsRequired)">
Installed OR NETFRAMEWORK45
</Condition>
<!-- Package the binaries in the msi -->
<Media Id="1" Cabinet="CABIIS.cab" EmbedCab="yes" />
<CustomAction Id="SetInstallLocationRootDirectory" Directory="INSTALLLOCATION" Execute="firstSequence" Value="[TARGET.INSTALLLOCATION]" />
<!-- Set the install location from the trigger file -->
<CustomAction Id="RunSCHEDULERInstall" Directory="TARGETDIR" Execute="deferred" Return="ignore" Impersonate="no" ExeCommand="[SCHEDULERIMPORTERFOLDER]ABC.NS.Scheduler.SCHEDULERService.exe install"/>
<CustomAction Id="RunSCHEDULERUninstall" Directory="TARGETDIR" Execute="deferred" Return="ignore" Impersonate="no" ExeCommand="[SCHEDULERIMPORTERFOLDER]ABC.NS.Scheduler.SCHEDULERService.exe uninstall"/>
<InstallExecuteSequence>
<Custom Action="RunSCHEDULERInstall" After="InstallFiles">NOT Installed</Custom>
<Custom Action="SetInstallLocationRootDirectory" After="CostFinalize" >Not Installed</Custom>
<Custom Action="RunSCHEDULERUninstall" After='InstallInitialize'>(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom>
</InstallExecuteSequence>
<!-- The directory structure for installation -->
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="INSTALLLOCATION" Name="WindowsService">
<Directory Id="SCHEDULERIMPORTERFOLDER" Name="ABC.NS.Scheduler.SCHEDULERService" />
<Directory Id="LOGFOLDER" Name="Log"/>
</Directory>
</Directory>
<Feature Id="ProductFeature" Title="ABC.NS.Scheduler.Deployment.SCHEDULER" Level="1">
<ComponentGroupRef Id="SCHEDULERServiceComponents" />
</Feature>
</Product>
</Wix>
Any help will be appreciated. Thanks.

Related

Custom Action to set INSTALLFOLDER path

So I created this customAction that gets me the path of another app using Registries
string value = Registry.GetValue(userRoot, key, -1).ToString();
session["INSTALLLOCATION"] = value;
And it works. The problem is how I send it back to the .wxs file and set the installation path of something to be that string value. I have this thing in the Wix file:
<CustomAction Id="CustomAction" Property="CustomAction2" Value="path=[INSTALLLOCATION]" />
<Binary Id="CustomActionBinary" SourceFile="$(var.ProAdmin_TargetDir)ExtractRegistryPath\bin\Debug\ExtractRegistryPath.CA.dll"/>
<CustomAction Id="CustomAction2" Impersonate="no" BinaryKey="CustomActionBinary" DllEntry="CustomAction1" Return="check" Execute="deferred"/>
<InstallUISequence>
<Custom Action="CustomAction" Before="CustomAction2" />
<Custom Action='CustomAction2' Before="ExecuteAction" />
</InstallUISequence>
This thing throws an 2762 error code.
You're getting error 2762 because you can't have deferred actions in the InstallUISequence. The custom action that populates the INSTALLLOCATION property should be called at the beginning of both the InstallUISequence and InstallExecuteSequence as an 'immediate' action - and - INSTALLLOCATION should be a folder in the Directory table.

Custom Actions not been called

I have some problems with managed code custom actions. I have 3 custom actions but only one of them is working. They are called at different times in InstallExecuteSequence but moving them makes no difference. I know there not getting very far because if I place a message box at the beginning of the routine(for debugging) it never get called . Where am I going wrong ? The actions are created like so.
<Binary Id="CA" SourceFile="$(var.ca.Custom.Actions.TargetDir)$(var.ca.Custom.Actions.TargetName).CA.dll" />
<CustomAction Id="WriteRemoveArpEntry" Property="CustomActionData" Value="PNAME=$(var.ProductName)" HideTarget="yes" />
<CustomAction Id="RemoveArpEntry" BinaryKey="CA" DllEntry="RemoveProductFromARP" Return="ignore" />
<CustomAction Id="SetValueforProductFolder" Property="CustomActionData" Value="SDIR=[INSTALLDIR];TDIR=[MANUDIR]\backup\$(var.ProductName)\$(var.VersionNumber)" HideTarget="yes" />
<CustomAction Id="Backup_Product_DIR" BinaryKey="CA" DllEntry="BackupDIR" Return="ignore" />
<CustomAction Id="WriteInstallAttemptData" Property="CustomActionData" Value="PRODUCTNAME=$(var.ProductName);APPVERSION=$(var.VersionNumber)" HideTarget="yes" />
<CustomAction Id="WriteInstallAttempt" BinaryKey="CA" DllEntry="WriteXMLServer" Return="ignore" />
I then call them here
<Custom Action="SetValueforProductFolder" Before="Backup_Product_DIR">NOT Installed AND NOT REMOVE</Custom>
<Custom Action="Backup_Product_DIR" Before="InstallFinalize">NOT Installed AND NOT REMOVE</Custom>
<Custom Action="WriteRemoveArpEntry" Before="InstallFinalize">NOT Installed AND NOT REMOVE</Custom>
<Custom Action="RemoveArpEntry" After="WriteRemoveArpEntry">NOT Installed AND NOT REMOVE</Custom>
<Custom Action="WriteInstallAttemptData" After="InstallFinalize">NOT Installed AND NOT REMOVE</Custom>
<Custom Action="WriteInstallAttempt" After="WriteInstallAttemptData">NOT Installed AND NOT REMOVE</Custom>
</InstallExecuteSequence>
The headers for the routines look like this
public static ActionResult BackupDIR(Session session)
{
public static ActionResult RemoveProductFromARP(Session session)
{
Public static ActionResult WriteXMLServer(Session session)
{
However only WriteXMLServer works. In the log file I get the following .
MSI (s) (BC:9C) [07:23:45:562]: Invoking remote custom action. DLL:
C:\Windows\Installer\MSI2E2A.tmp, Entrypoint: BackupDIR CustomAction
Backup_Product_DIR returned actual error code 1154 but will be
translated to success due to continue marking
In the one that works I get
MSI (s) (BC:A0) [07:24:25:994]: Invoking remote custom action. DLL:
C:\Windows\Installer\MSICC20.tmp, Entrypoint: WriteXMLServer SFXCA:
Extracting custom action to temporary directory:
C:\Windows\Installer\MSICC20.tmp-\ SFXCA: Binding to CLR version
v4.0.30319
The answer was very simple I forgot the
[CustomAction]
For the other two routines.

Wix silent installation of MSI can we stop creation of directory

I am doing WIX MSI slient installation,and also there is some custom actions checking in between if the customaction fails how to roll back or end the slient installation process of the msi??I am copying files and also starting windows service using Wix installation.When ever customaction fails how i can stop the creation of directory and starting of the windows service??
[CustomAction]
public static ActionResult PrerequisiteCheck(Session session)
{
if (Status.IsServiceAvailable && Status.IsPrinter)
{
return ActionResult.Success;
}
else
{
//Stop Installer
return ActionResult.Failure;
}
}
<CustomAction Id="CheckPrerequiste" BinaryKey="BIN_CustomAction" DllEntry="CheckPrerequiste" Return="ignore" Execute="immediate" />
<InstallExecuteSequence> <Custom Action="CA_PrerequisiteCheck" After="InstallExecute" > </Custom>
</InstallExecuteSequence>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLLOCATION" Name="Service">
<Component Id="WindowsService" Guid="AA34D3C1-26F1-4A7E-A226-1AB01501C67C">
<File Id="00690A65EA1A3EFEB7607285DBA0C8C5" KeyPath="yes" Source="WindowsService.Svc.exe" />
<ServiceInstall Id="Service" Name="Service" DisplayName="Windows Service" Description="Windows Service" Start="auto" ErrorControl="normal" Type="ownProcess" />
<ServiceControl Id="sc_Service" Name="Service" Stop="both" Remove="uninstall" Wait="yes" />
<Component Id="WindowsSvcexe" Guid="06ABF18B-DEDE-4D98-AF9F-8384539A6BC3"> <File Id="49215CE1A25380930C771772AD14519B" KeyPath="yes" Source="WindowsService.Svc.exe.config" /> </Component> </Component>
</Directory>
</Directory>
</Directory>
The installation sequence is divided into two main stages; immediate and deferred. The main reason of dividing an installation into two phases (UI and Execution) is supplying roll-back if an error occurs. All actions in the execution phase, between InstallInitialize and InstallFinalize are included in the roll-back, which is called the deferred stage. The initial phase, where the roll-back script is being prepared but the roll-back protection has not started yet is called immediate stage.
The UI sequence does not have any roll-back feature, therefore actions that alter the system should never take place there.
Custom actions that make system changes should be marked as deferred and should be scheduled to run between InstallInitialize and InstallFinalize in the execution phase. Roll-back actions should be supplied by the developer for custom actions:
…
<CustomAction Id=”myaction” Execute=”deferred” Return=”check” />
…
<InstallUISequence>
<Custom Action=”myaction” After=”CostFinalize” />
<Custom Action=”myaction2” After=”myaction” />
</InstallUISequence>
<InstallExecuteSequence>
<Custom Action=”myaction3” After=”InstallInitialize” />
<Custom Action=”myaction4” After=”myaction3” />
</InstallExecuteSequence>
Custom actions that are deferred execute during the Execute sequence’s rollback-protected phase. To give those actions rollback capabilities, separate custom actions that undo the work should be authored.
Rollback actions are scheduled before the action they are meant to revert in case of an error:
<CustomAction Id="systemChangingCA" Execute="deferred" Script="vbscript">
msgbox "Your system has been changed"
</CustomAction>
<CustomAction Id="rollbackSystemChangingCA" Execute="rollback" Script="vbscript">
msgbox "System changes are undone"
</CustomAction>
<CustomAction Id="causeError" Execute="deferred" Script="vbscript">
Err.Raise 507
</CustomAction>
These are scheduled as:
<InstallExecuteSequence>
<Custom Action="rollbackSystemChangingCA" Before="systemChangingCA" />
<Custom Action="systemChangingCA" After="InstallInitialize" />
<Custom Action="causeError" After="systemChangingCA" />
</InstallExecuteSequence>
In this example, systemChangingCA will run during deferred phase of InstallExecuteSequence. When causeError runs afterwards, it causes an exception to be thrown, which triggers a rollback. Then rollbackSystemChangingCA runs.
Wix toolset also provides its own custom action for stimulating a rollback called WixFailWhenDeferred. It is a part of WixUtilExtension and you could use it to test your rollback methods.
The folders created by WiX itself should be removed automatically during a rollback.
You can learn more about the overall concept of Microsoft Installer and WiX from the book of Nick Ramirez: "A Developer's Guide to Windows Installer XML". It has many examples and cases including the ones above.

How can I set recovery-options of a service with WiX?

I have following .wxs-file:
<?xml version="1.0" encoding="UTF-8"?>
<?define ProductVersion="x.x.x.x" ?>
<?define UpgradeCode="{**MYGUID**}" ?>
<?define Manufacturer="My Company" ?>
<?define ProductName="My Product" ?>
<?define SkuName="MyProduct" ?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*"
Name="$(var.ProductName)"
Language="1033"
Version="$(var.ProductVersion)"
Manufacturer="$(var.Manufacturer)"
UpgradeCode="$(var.UpgradeCode)">
<Package InstallerVersion="301"
Compressed="yes"
InstallPrivileges="elevated"
InstallScope="perMachine"
Platform="x86" />
<Media Id="1"
Cabinet="$(var.SkuName).cab"
EmbedCab="yes" />
<Directory Id="TARGETDIR"
Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="ManufacturereDirectory"
Name="$(var.Manufacturer)">
<Directory Id="ProductDirectory"
Name="$(var.ProductName)" />
</Directory>
</Directory>
</Directory>
<ComponentGroup Id="MainComponentGroup">
<Component Directory="ProductDirectory">
<File Name="$(var.MyProject.TargetFileName)"
Source="$(var.MyProject.TargetPath)"
KeyPath="yes"
Vital="yes" />
<ServiceInstall Id="SeviceInstall"
Name="$(var.ProductName)"
DisplayName="$(var.ProductName)"
Type="ownProcess"
Interactive="no"
Start="auto"
Vital="yes"
ErrorControl="normal"
Account="LOCALSYSTEM">
</ServiceInstall>
<ServiceControl Id="ServiceControl_Start"
Name="$(var.ProductName)"
Start="install"
Wait="no" />
<ServiceControl Id="ServiceControl_Stop"
Name="$(var.ProductName)"
Stop="both"
Remove="uninstall"
Wait="yes" />
</Component>
</ComponentGroup>
<Feature Id="MainFeature"
Level="1">
<ComponentGroupRef Id="MainComponentGroup" />
</Feature>
<Upgrade Id="$(var.UpgradeCode)">
<UpgradeVersion Property="UPGRADEFOUND"
Minimum="0.0.0.1" IncludeMinimum="yes"
Maximum="$(var.ProductVersion)" IncludeMaximum="yes"
OnlyDetect="no"
IgnoreRemoveFailure="yes"
MigrateFeatures="yes"/>
</Upgrade>
<CustomAction Id="ServiceRestarter"
Directory="ProductDirectory"
ExeCommand=""[SystemFolder]sc.exe" failure "$(var.ProductName)" reset= 60 actions= restart/0"
Impersonate="no" />
<InstallExecuteSequence>
<InstallExecute Before="RemoveExistingProducts" />
<RemoveExistingProducts Before="InstallFinalize" />
<Custom Action="ServiceRestarter" After="InstallFinalize"><![CDATA[NOT Installed]]></Custom>
</InstallExecuteSequence>
</Product>
</Wix>
Before that, I've tried:
<CustomAction Id="ServiceRestarter"
Property="QtExecCmdLine"
Value='"[SystemFolder]sc.exe" failure "$(var.ProductName)" reset= 60 actions= restart/0' />
which apparently called sc.exe - but changed nothing ...
Before that I've tried:
<ServiceInstall Id="SeviceInstall"
Name="$(var.ProductName)"
DisplayName="$(var.ProductName)"
Type="ownProcess"
Interactive="no"
Start="auto"
Vital="yes"
ErrorControl="normal"
Account="LOCALSYSTEM">
<ServiceConfig Id="ServiceConfig"
DelayedAutoStart="yes"
OnInstall="yes"
OnReinstall="yes"
OnUninstall="no"
FailureActionsWhen="failedToStopOrReturnedError" />
<ServiceConfigFailureActions Id="ServiceRestarter"
OnInstall="yes"
OnReinstall="yes"
OnUninstall="no"
ResetPeriod="0">
<Failure Action="restartService" Delay="0" />
<Failure Action="restartService" Delay="0" />
<Failure Action="restartService" Delay="0" />
</ServiceConfigFailureActions>
</ServiceInstall>
which did not work, as the MsiServiceConfigFailureActions table does not work if using an installer < 5.0, and even if using InstallerVersion="500" the only thing I get is an error:
Serivce 'My Product' (My Product) could not be configured. This could
be a problem with the package or your permissions. Verify that you
have sufficient privileges to configure system services.
(and yes, ... I've tried InstallPrivilges="elevated" also - but ... the real issue is Action="restartService" according to this)
So ... using a CustomAction is the way to go (or not?).
I have following output of the log
MSI (s) (34:28) [13:56:46:914]: Note: 1: 1722 2: ServiceRestarter 3: C:\Program Files (x86)\My Company\My Product\ 4: "C:\Windows\SysWOW64\sc.exe" failure "My Product" reset= 60 actions= restart/0
MSI (s) (34:28) [13:56:46:914]: Note: 1: 2205 2: 3: Error
MSI (s) (34:28) [13:56:46:914]: Note: 1: 2228 2: 3: Error 4: SELECT Message FROM Error WHERE Error = 1722
MSI (c) (2C:0C) [13:56:46:914]: Font created. Charset: Req=0, Ret=0, Font: Req=MS Shell Dlg, Ret=MS Shell Dlg
Error 1722. There is a problem with this Windows Installer package. A program run as part of the setup did not finish as expected. Contact your support personnel or package vendor. Action ServiceRestarter, location: C:\Program Files (x86)\My Company\My Product\, command: "C:\Windows\SysWOW64\sc.exe" failure "My Product" reset= 60 actions= restart/0
MSI (s) (34:28) [13:56:48:849]: Note: 1: 2205 2: 3: Error
MSI (s) (34:28) [13:56:48:849]: Note: 1: 2228 2: 3: Error 4: SELECT Message FROM Error WHERE Error = 1709
MSI (s) (34:28) [13:56:48:849]: Product: My Product -- Error 1722. There is a problem with this Windows Installer package. A program run as part of the setup did not finish as expected. Contact your support personnel or package vendor. Action ServiceRestarter, location: C:\Program Files (x86)\My Company\My Product\, command: "C:\Windows\SysWOW64\sc.exe" failure "My Product" reset= 60 actions= restart/0
Action ended 13:56:48: ServiceRestarter. Return value 3.
Action ended 13:56:48: INSTALL. Return value 3.
Can anybody help me out?
edit
I've used the old ServiceConfig-extension:
<util:ServiceConfig xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"
FirstFailureActionType="restart"
SecondFailureActionType="restart"
ThirdFailureActionType="restart"
ResetPeriodInDays="1"
RestartServiceDelayInSeconds="20" />
which gives me a following build-error:
error CNDL0200: The ServiceInstall element contains an unhandled
extension element 'util:ServiceConfig'. Please ensure that the
extension for elements in the
'http://schemas.microsoft.com/wix/UtilExtension' namespace has been
provided.
I know that I can resolve this error by using -ext WixUtilExtension via commandline - but I want to use Visual Studio for building ... So how can I adapt the build-command?
Only chance is to add a reference to WixUtilExtension.dll to my project.
I can see that you've only tried the ServiceConfig element, which came with MSI 5.0. However, there's another ServiceConfig element in UtilExtension, which has been there for a long time and it seems that the thread you mention in your question confirms that it works.
The util:ServiceConfig element contains 3 parameters you'd like to use: FirstFailureActionType, SecondFailureActionType and ThirdFailureActionType, all accepting the same enumeration of values - none, reboot, restart and runCommand.
Try it out and if it works, it is far better choice than a custom action.
For WIX V 4.0, building with VS2015, the following works:
1: Ensure that WixUtilExtension.dll assembly is referenced by WIX project.
2: Add http://wixtoolset.org/schemas/v4/wxs/util ns to root Wix element. Note that this is the correct NS for WIX 4.0 (NOT http://schemas.microsoft.com/wix/UtilExtension as for previous versions).
<Wix
xmlns="http://wixtoolset.org/schemas/v4/wxs"
xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util"
>
3: Ensure that ServiceConfig element is prefixed with correct namespace reference.
<ServiceInstall
Id="MyService"
Type="ownProcess"
Name="MyService"
DisplayName="MyService"
Description="My Service"
Start="auto"
Account="[SERVICEACCOUNT]"
Password="[SERVICEPASSWORD]"
ErrorControl="normal"
>
<util:ServiceConfig
FirstFailureActionType='restart'
SecondFailureActionType='restart'
ThirdFailureActionType='restart'
RestartServiceDelayInSeconds='30'
ResetPeriodInDays='1'/>
</ServiceInstall>
In Visual Studio, to avoid using -ext in CLI you may do the following:
Of course, you add a resource: <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
then, in Solution Explorer -> References -> Add..
WixUtilExtension.dll
After that everything works like a charm.
(wix 3.10)
Of course, if you do use the second ServiceConfig from utils. Like <util:ServiceConfig blablabla

can't pass properties to WiX custom action

I've read How do I pass msiexec properties to a WiX C# custom action? , but that didn't answer my question, or maybe I just don't see what I am doing wrong.
My install package fails to install, and the logs say that my property wasn't found in the custom actions collection. My code is:
<CustomAction Id="SetCustomActionDataValue" Return="check" Property="Itp.Configurator.WixCustomAction" Value="G=G2" />
<CustomAction Id="CreateDatabase" BinaryKey="Binary1" DllEntry="CreateDatabase" Execute="deferred" Return="check" />
<InstallExecuteSequence>
<Custom Action='SetCustomActionDataValue' After="InstallFiles"/>
<Custom Action='CreateDatabase' After="SetCustomActionDataValue">
NOT Installed AND NOT PATCH
</Custom>
</InstallExecuteSequence>
And code inside the custom action is:
string Property1 = session.CustomActionData["G"];
The name of the property in your first element must be exactly the same as the name of the deferred custom action you'd like to pass the value to. So, if the deferred action is CreateDatabase, then the first element should look like this:
<CustomAction Id="SetCustomActionDataValue" Return="check" Property="CreateDatabase" Value="G=G2" />