Why is CostFinalize modifying my custom property in one install and not the other? - wix

I have two installs with virtually identical code. I set a custom property like this:
<SetProperty Id="MYCONFIGPATH" Value="[CONFIGPATH]" Before="CostInitialize"/>
And then reference that property in a component:
<Component Id="CopyConfigFromConfigPath" Guid="{XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" MultiInstance="yes">
<Condition>CONFIGPATH</Condition>
<CopyFile SourceProperty="MYCONFIGPATH" DestinationDirectory="ConfigBOR" DestinationName="ConfigBOR.xml" Id="CopyConfigBOR" />
</Component>
I'm not certain this is what's causing the failure to copy this file but I suspect it is:
MSI (s) (64:6C) [14:03:42:383]: PROPERTY CHANGE: Modifying MYCONFIGPATH property. Its current value is 'C:\Installs\ConfigBOR.xml'. Its new value: 'C:\Installs\ConfigBOR.xml\'.
Notice the trailing backslash. This happens shortly after starting CostFinalize. Just above that log entry are some suspicious looking entries but I can't figure out what they mean so I'm not sure they're relevant:
MSI (s) (64:6C) [14:03:42:380]: Doing action: CostFinalize
MSI (s) (64:6C) [14:03:42:380]: Note: 1: 2205 2: 3: ActionText
and
MSI (s) (64:6C) [14:03:42:382]: Note: 1: 2205 2: 3: Patch
MSI (s) (64:6C) [14:03:42:383]: Note: 1: 2205 2: 3: Condition
I have identical code in another installer (BOR is replaced with the product name in that one) but it doesn't modify this property and does correctly copy this file. Why doesn't it work here?

I don't think your question provides enough information to answer this for certain, but my psychic powers tell me that MYCONFIGPATH is in the Directory table in one package but not in the other. Thus the directory resolution phase of CostFinalize affects the two packages differently.

C:\Installs\ConfigBOR.xml did not exist. I guess WIX picked up on that and, instead of throwing an error, decided to check if a directory with that name were present.

Related

What happens if a rollback custom action fails?

What happens if a rollback custom action fails? Do I need to specify a Return attribute in Wix CustomAction element for a rollback custom action?
I did a quick test. I created a binary custom action:
This is a C++ code:
UINT __stdcall ForceInstallFailure(MSIHANDLE hModule)
{
return ERROR_INSTALL_FAILURE;
}
A Wix code:
<CustomAction Id="CA_ForceInstallFailure" BinaryKey="Bin_CAInst"
DllEntry="ForceInstallFailure"
Execute="rollback" Return="check" Impersonate="no" />
Wix translated it into type 3329:
Type 1 (DLL generated from a binary stream called through an entry point) +
3328 (msidbCustomActionTypeInScript + msidbCustomActionTypeNoImpersonate + msidbCustomActionTypeRollback)
I simulated a rollback with https://wixtoolset.org/docs/v3/customactions/wixfailwhendeferred/
This is what I get in MSI log:
Rollback: CA_ForceInstallFailure
MSI (s) (90:B4) [02:18:54:053]: Executing op: ActionStart(Name=CA_ForceInstallFailure,,)
MSI (s) (90:B4) [02:18:54:053]: Executing op: CustomActionRollback(Action=CA_ForceInstallFailure,ActionType=3329,Source=BinaryData,Target=ForceInstallFailure,)
MSI (s) (90:14) [02:18:54:053]: Invoking remote custom action. DLL: C:\Windows\Installer\MSIC523.tmp, Entrypoint: ForceInstallFailure
CustomAction CA_ForceInstallFailure returned actual error code 1603 but will be translated to success due to continue marking
It looks like Windows Installer doesn't check a custom action return value during a rollback, even though I didn't mark it specifically as Return="ignore" which would translate to msidbCustomActionTypeContinue addition.
Although it logically seems the correct behavior, I could not find any official documentation that describes this.
The Windows Installer does not have rollback for rollback, so it ignores custom action failures during rollback.

How to make the SSIS package status to failure when propagate was set to false for a Sequence container

I have an SSIS package with for each loop > sequence container. The sequence container is trying to read file from For each loop and process its data. The requirement was to not fail the entire package when any exception happened in processing a file but to continue processing the next file until all the files were processed from the for each loop. For this, I have set the Propagate variable for the sequence container to False. I have also added email step on On Error event of Sequence container. The package is running as expected and able to process all files even when any exception happened with any file. But I would like the status of my SSIS package to be failed finally since one of the files got failed. How can I achieve that ?
Did you try this options?
(SSIS version in russian on the left side but it's sequence container)
View -> Properties window -> Then click on your sequence container and it will show you ther properties of sequence container.
If i were you first of all i would try property "FailPackageOnFailture" - it should cover your question if i get it right.
P.S. Also you can see the whole properties of your project when you click on a free place in your project
UPDATED (after comments and more clear understanding task):
The idea is - set this param Maximum ErrorCount for SQ as max as you want - in this case it wont stop the package because 1 of the files was failed in SQ and next file will process, but it should stop package after SQ will finish his work because you don't change MaximumErrorCount for package.
Important - a value of zero sets the error count threshold to infinity and package or task never get's Failure

Wix IIS Version check launch condition not working

Hi I am trying to add launch condition to check IIS Version installed is greater than 7 if not it should display compliance message.
<PropertyRef Id="IISMAJORVERSION"/>
<Condition Message="Install requires IIS 7 or higher">
<![CDATA[IISMAJORVERSION AND (IISMAJORVERSION >= #7)]>
</Condition>
Also tried IISMAJORVERSION >= "#7" and IISMAJORVERSION >= "#7" but
it is not showing condition message on the machines which doesn't have IIs installed. Please help.
As IISMAJORVERSION is a string we cannot perform greater than or lesser than. Hence I modified my condition to below.
<PropertyRef Id="IISMAJORVERSION"/>
<Condition Message="Installer requires IIS 6 or 7 or higher versions installed on the machine.">
<![CDATA[(IISMAJORVERSION <> "") AND (IISMAJORVERSION <> "#1") AND (IISMAJORVERSION <> "#2") AND (IISMAJORVERSION <> "#3") AND (IISMAJORVERSION <> "#4") AND (IISMAJORVERSION <> "#5")]]>
</Condition>
Check MSI: Open your compiled MSI in Orca (or an equivalent tool - see towards bottom). Are there entries in the LaunchCondition table? I can't see how that condition could compile - in its current form. You might have linked with old object files or something like that. Meaning that you current build is actually failing to produce a new MSI file, you are using an old one without noticing.
Condition: I think you have a mistake in the condition formatting, maybe try something like this:
<Condition Message="Install requires IIS 7 or higher">
<![CDATA[IISMAJORVERSION AND (IISMAJORVERSION >= "#7")]]>
</Condition>
Notice the double brackets at the end and the < and > characters at both ends and the quotes around #7. I didn't check the actual condition. Isn't it enough with the second part?
Alternatively use an escape character as shown here.

Too Many Events Using DTF InstallLogModes

I'm currently logging "everything" using the following flags:
const DTF.InstallLogModes logEverything = DTF.InstallLogModes.FatalExit |
DTF.InstallLogModes.Error |
DTF.InstallLogModes.Warning |
DTF.InstallLogModes.User |
DTF.InstallLogModes.Info |
DTF.InstallLogModes.ResolveSource |
DTF.InstallLogModes.OutOfDiskSpace |
DTF.InstallLogModes.ActionStart |
DTF.InstallLogModes.ActionData |
DTF.InstallLogModes.CommonData |
DTF.InstallLogModes.Progress |
DTF.InstallLogModes.Initialize |
DTF.InstallLogModes.Terminate |
DTF.InstallLogModes.ShowDialog;
DTF.Installer.SetInternalUI(DTF.InstallUIOptions.Silent);
var handler = new DTF.ExternalUIRecordHandler(ProcessMessage);
DTF.Installer.SetExternalUI(handler, logEverything);
DTF.Installer.EnableLog(logEverything, logPath, true, true);
DTF.Installer.InstallProduct(installerPath, commandLine);
This has the effect of writing an enormous number of events to the log file.
For example, I'm seeing thousands of these:
MSI (s) (14:A0) [11:33:50:764]: Component: comp_27E5179987044690962CE98B3F95FD72; Installed: Local; Request: Null; Action: Null; Client State: Local
MSI (c) (4C:8C) [11:34:17:869]: Creating MSIHANDLE (592) of type 790531 for thread 8076
MSI (c) (4C:8C) [11:34:17:893]: Closing MSIHANDLE (592) of type 790531 for thread 8076
How do I disable those extremely verbose messages in the log? I need to keep the Progress events.
If you don't want them, don't set the bts in the API call. Just set progress. However, you do need to get hold of the error messages and warnings to display them.
However....what's your goal here? You don't need to re-invent the logging that you can get in other ways. The purpose of using that external UI call API is that you are now in charge of all the UI for the install. This isn't really about logging, it's about you being responsible for the UI, and a standard install will typically show all those messages in one form or another. For example, along with progress messages you get action messages that says what's going on (file name being copied, etc). If that is an actual product that you are installing, then you really need to show error messages, files in use dialogs, warnings, or you're simply hiding everything that goes on.
Link to underlying AP docs: https://msdn.microsoft.com/en-us/library/aa370573(v=vs.85).aspx

Can't run a managed custom action on uninstall

I have a custom action which should be run on uninstall. But for unknown reason the msiexec says "There is a problem with this Windows Installer package. A DLL required for this install to complete could not be run. Contact your support personnel or package vendor.". The code goes below:
<Binary SourceFile="SetupWiX.CA.dll" Id="Binary1" />
<CustomAction Id="DropDatabase" BinaryKey="Binary1" DllEntry="DropDatabase" Execute="deferred" Return="check"/>
<Custom Action='DropDatabase' After="SetCustomActionDataValue_DropDatabase">Installed</Custom>
I have few other custom actions that run on install and they run fine. Everything is same there except the conditions.
So how can I make my custom action run on uninstall correctly?
I've created a blank wix setup project, and a simple custom action that shows message box on uninstall, and it works fine. I don't know what is the problem with my first custom action.
I use the same DLL on install and uninstall.
The error log goes below:
Action start 16:07:34: INSTALL.
Action start 16:07:34: ValidateProductID.
Action ended 16:07:34: ValidateProductID. Return value 1.
Action start 16:07:34: CostInitialize.
Action ended 16:07:34: CostInitialize. Return value 1.
Action start 16:07:34: FileCost.
Action ended 16:07:34: FileCost. Return value 1.
Action start 16:07:34: CostFinalize.
Action ended 16:07:34: CostFinalize. Return value 1.
Action start 16:07:34: InstallValidate.
Action ended 16:07:34: InstallValidate. Return value 1.
Action start 16:07:34: InstallInitialize.
Action ended 16:07:37: InstallInitialize. Return value 1.
Action start 16:07:37: ProcessComponents.
Action ended 16:07:37: ProcessComponents. Return value 1.
Action start 16:07:37: UnpublishFeatures.
Action ended 16:07:37: UnpublishFeatures. Return value 1.
Action start 16:07:37: RemoveFiles.
Action ended 16:07:37: RemoveFiles. Return value 0.
Action start 16:07:37: InstallFiles.
Action ended 16:07:37: InstallFiles. Return value 1.
Action start 16:07:37: DropDatabase.
Action ended 16:07:37: DropDatabase. Return value 1.
Action start 16:07:37: RegisterUser.
Action ended 16:07:37: RegisterUser. Return value 0.
Action start 16:07:37: RegisterProduct.
Action ended 16:07:37: RegisterProduct. Return value 1.
Action start 16:07:37: PublishFeatures.
Action ended 16:07:37: PublishFeatures. Return value 1.
Action start 16:07:37: PublishProduct.
Action ended 16:07:37: PublishProduct. Return value 1.
Action start 16:07:37: InstallFinalize.
CustomAction DropDatabase returned actual error code 1154 (note this may not be 100% accurate if translation happened inside sandbox)
MSI (s) (D4:DC) [16:07:41:650]: Product: MyProduct -- Error 1723. There is a problem with this Windows Installer package. A DLL required for this install to complete could not be run. Contact your support personnel or package vendor. Action DropDatabase, entry: DropDatabase, library: C:\Windows\Installer\MSI4DEF.tmp
Error 1723. There is a problem with this Windows Installer package. A DLL required for this install to complete could not be run. Contact your support personnel or package vendor. Action DropDatabase, entry: DropDatabase, library: C:\Windows\Installer\MSI4DEF.tmp
Action ended 16:07:41: InstallFinalize. Return value 3.
Action ended 16:07:42: INSTALL. Return value 3.
The problem was in my custom action method being private, not public.