How can I stop an .exe on repair, update and delete in wix? - wix

In my wix I use the following declaration:
<ComponentGroup Id="BinComponents" Directory="BIN">
<Component Id="BinComponent" Guid="23D229D0-06EE-49f4-80B4-6D7136500721">
<File Id="MyProjectOutput" Name="MyProject.exe" Source="MyProject\bin\MyProject.exe"/>
<ServiceControl Id="RemoveService"
Stop="both"
Remove="both"
Name="MyProject.exe"
Wait="yes" /> <!-- Stop running MyProject instances -->
</Component>
</ComponentGroup>
My Repro:
At first, I run my installation as usual. After the installation, I start my web application. An .exe appears in the task manager as usual:
I want to end this .exe on a repair, update or uninstall. So I start my .msi again and choose repair:
Now my problem: After pressing 'Repair', I expect the following dialog because of the declared ServiceControl:
But it doesn´t. Instead, the following dialog appears:
When I log the setup, the log shows the following lines:
MSI (s) (A8:DC) [10:16:28:227]: Executing op: ActionStart(Name=StopServices,Description=Stopping services,Template=Service: [1])
Action 10:16:28: StopServices. Stopping services
MSI (s) (A8:DC) [10:16:28:228]: Executing op: ProgressTotal(Total=1,Type=1,ByteEquivalent=1300000)
MSI (s) (A8:DC) [10:16:28:228]: Executing op: ServiceControl(,Name=MyProject.exe,Action=2,Wait=1,)
MSI (s) (A8:DC) [10:16:28:228]: Executing op: ActionStart(Name=DeleteServices,Description=Deleting services,Template=Service: [1])
Action 10:16:28: DeleteServices. Deleting services
MSI (s) (A8:DC) [10:16:28:228]: Executing op: ProgressTotal(Total=1,Type=1,ByteEquivalent=1300000)
MSI (s) (A8:DC) [10:16:28:229]: Executing op: ServiceControl(,Name=MyProject.exe,Action=8,Wait=1,)
MSI (s) (A8:DC) [10:16:28:229]: Executing op: ActionStart(Name=InstallFiles,Description=Copying new files,Template=File:
[1], Directory: [9], Size: [6])
[...]
MSI (s) (7C:28) [09:06:21:950]: RESTART MANAGER: Did detect that a critical application holds file[s] in use, so a reboot will be necessary.
MSI (s) (7C:28) [09:06:21:950]: Note: 1: 1610
MSI (s) (7C:28) [09:06:21:950]: Note: 1: 2205 2: 3: Error
MSI (s) (7C:28) [09:06:21:950]: Note: 1: 2228 2: 3: Error 4: SELECT `Message` FROM `Error` WHERE `Error` = 1610
Next to a Repair I also have tried an Update with the same results.
Perhaps any declaration missing?
Note: When I close the MyApp.exe in the task manager, the message does not appear, so the MyApp.exe is definitely responsible for the problem.

You should post the entire log somewhere. The root cause is that a repair shouldn't routinely require files to be replaced. So if you literally installed your product, ran the exe, and then a repair needs to replace files, then the issue is not that files-in-use dialog - it's that the installed product is broken, so required files or registry entries have been removed. The application event log should have MsiInstaller entries that describe a missing component. So look at that root cause first.
After fixing that it should be very rare for a repair to need to replace files, so it may not be worth worrying about. But you could look at integrating your app with Restart Manager or using the WiX util CloseApplication.

The warning dialog that you are seeing is from "InstallValidate" standard action.
I have run into a similar issue in the past . I fixed it by making use of a single service control element instead of multiple service control elements, for the same service id.
In my case, i had multiple service control elements for the same service id.
This is as per the link at
http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/Upgrade-uninstall-restart-issue-td7586315.html
This did the trick for me. Numerous users have reported the same behavior, though its not officially documented.
Having a single service control element makes Restart Manager take note of the entry in the Service Control table and will prevent Restart Manager from listing the service in the RMFilesInUse dialog box or will prevent Restart Manager
from throwing up warning messages informing the user that a restart might be required.
Here is one more link
Can't start windows service with WiX
My experiments have shown me that there is definitley a link between the number of service control elements and Restart Manager
http://microsoft.public.windows.msi.narkive.com/OOuQQAsw/controlling-restart-manager-behaviour
The other option was to totally disable Restart Manager using the property RESTARTMANAGERCONTROL, In case, you disable the RestartManager, you might be prompted for reboots(you might want to test it once) and the legacy "Files in Use" mechanism kicks off. Disabling Restart Manager is a conscious decision by the concerned msi developer and at times becomes necessary.
I am not sure about how your Service Control table looks like. Just wanted to share my experience with you.
Hopefully it helps.
Regards,
Kiran Hegde

Related

Installer flags file in use when it is not

I have a WIX installer which updates an SNMP Agent dll. I have a custom action which stops the SNMP service. When the installer runs the log file always says the file is in use when it is not. When reviewing the installer log the log entries appear to be bassackwards. File copy log entries are written after the installed services and SNMP service have all already started. The file is updated and the SNMP Service starts with the newly copied file. No reboot is necessary however MSI is setting the reboot flag. Here's a snippet of my log file. Can anyone make sense of this order of operations issue?
`
...
Action ended 14:59:57: StopSnmpService. Return value 1.
...
MSI (s) (4C:04) [14:59:58:982]: Doing action: InstallFiles
...
MSI (s) (4C:04) [14:59:59:029]: Doing action: InstallServices
Action 14:59:59: InstallServices. Installing new services
Action start 14:59:59: InstallServices.
InstallServices: Service:
Action ended 14:59:59: InstallServices. Return value 1.
MSI (s) (4C:04) [14:59:59:029]: Doing action: StartServices
Action 14:59:59: StartServices. Starting services
Action start 14:59:59: StartServices.
StartServices: Service: Starting services
Action ended 14:59:59: StartServices. Return value 1.
...
MSI (s) (4C:04) [14:59:59:045]: Doing action: StartSnmpService
...
MSI (s) (4C:04) [14:59:59:560]: File: C:\Program Files\Corner Bowl\Server Manager 2022\cbsmsnmpagent.dll; Overwrite; Won't patch; Existing file is a lower version
MSI (s) (4C:04) [14:59:59:560]: Source for file 'cbsmsnmpagent.dll' is compressed
InstallFiles: File: cbsmsnmpagent.dll, Directory: C:\Program Files\Corner Bowl\Server Manager 2022, Size: 19968
MSI (s) (4C:04) [14:59:59:560]: Re-applying security from existing file.
Info 1603. The file C:\Program Files\Corner Bowl\Server Manager 2022\cbsmsnmpagent.dll is being held in use. Close that application and retry.
MSI (s) (4C:04) [15:00:02:919]: Verifying accessibility of file: cbsmsnmpagent.dll
...
`
This is a downside of reinventing the wheel with a custom action. If you used the ServiceControl element then MSI would know that this service will be stopped and the file won't really be in use. But since your doing it out of process with custom code it doesn't know this and you get an erroneous message.

Unable to uninstall the application which is installed using wix installer

I have used wix installer to create an installer for my c# application.
Installation happened fine, but I am not able to uninstall the application. I see below the logs
MSI (s) (78:AC) [15:32:06:199]: Machine policy value 'Debug' is 0
MSI (s) (78:AC) [15:32:06:199]: ******* RunEngine:
******* Product: C:\wix\Installer\\bin\Debug\MyService-Debug-x86.msi
******* Action:
******* CommandLine: **********
MSI (s) (78:AC) [15:32:06:207]: Machine policy value 'DisableUserInstalls' is 0
MSI (s) (78:AC) [15:32:06:326]: Note: 1: 2203 2:
C:\Windows\Installer\inprogressinstallinfo.ipi 3: -2147287038
MSI (s) (78:AC) [15:32:06:327]: Machine policy value
'LimitSystemRestoreCheckpointing' is 0
MSI (s) (78:AC) [15:32:06:327]: Note: 1: 1717 2: My Service (32bit)
MSI (s) (78:AC) [15:32:06:327]: Note: 1: 2205 2: 3: Error
MSI (s) (78:AC) [15:32:06:327]: Note: 1: 2228 2: 3: Error 4: SELECT
`Message` FROM `Error` WHERE `Error` = 1717
MSI (s) (78:AC) [15:32:06:327]: Calling SRSetRestorePoint API.
dwRestorePtType: 1, dwEventType: 102, llSequenceNumber: 0, szDescription:
"Removed My Service (32bit)".
MSI (s) (78:AC) [15:32:06:330]: The System Restore service is disabled.
Returned status: 1058. GetLastError() returned: 1058
MSI (s) (78:AC) [15:32:06:332]: File will have security applied from OpCode.
MSI (s) (78:AC) [15:32:06:362]: SOFTWARE RESTRICTION POLICY: Verifying
package --> 'C:\wix\Installer\\bin\Debug\MyService-Debug-x86.msi' against
software restriction policy
MSI (s) (78:AC) [15:32:06:363]: Note: 1: 2262 2: DigitalSignature 3:
-2147287038
MSI (s) (78:AC) [15:32:06:363]: SOFTWARE RESTRICTION POLICY:
C:\wix\Installer\\bin\Debug\MyService-Debug-x86.msi is not digitally signed
MSI (s) (78:AC) [15:32:06:365]: SOFTWARE RESTRICTION POLICY:
C:\wix\Installer\\bin\Debug\MyService-Debug-x86.msi is permitted to run at
the 'unrestricted' authorization level.
MSI (s) (78:AC) [15:32:06:366]: MSCOREE not loaded loading copy from
system32
MSI (s) (78:AC) [15:32:06:374]: End dialog not enabled
MSI (s) (78:AC) [15:32:06:374]: Original package ==>
C:\wix\Installer\\bin\Debug\MyService-Debug-x86.msi
MSI (s) (78:AC) [15:32:06:374]: Package we're running from ==>
C:\Windows\Installer\152e2e.msi
While creating an installer, I never thought of digitally signing and all. Is it anything to do with signing? Totaly lost and need help
I have even tried with running uninstallation using the command line (admin mode) but no luck
msiexec.exe /x "C:\wix\Installer\\bin\Debug\MyService-Debug-x86.msi" /L*V "C:\work\wix.log"
it says
Another version of this product is already installed. Installation of this version cannot continue. To configure or remove the existing version of this product, use Add/Remove Programs on the Control Panel.
I might have to rebuild the installer code before uninstalling. Is it possible that some "guid" has changed related to the installer? anything I have to check inside registry?
Updated the question with Wix Code
The issue started appearing after I added custom actions. The responsibility of custom action is to get parameters from the installer and update the appsettings.json. but this uninstallation issue not allowing me to continue implementation.
<Property Id="APPLICATIONLOG.PATHFORMAT" Secure="yes"/>
<Binary Id="CustomActionDLL"
SourceFile="..\..\Installer\CustomActions\bin\$(var.Configuration)\CustomAction.CA.dll" />
<CustomAction Id="SetPropertyAppLogPathId"
Property="SetPropertyAppLogPathProperty"
Value="APPLICATIONLOG.PATHFORMAT=[APPLICATIONLOG.PATHFORMAT]"/>
<CustomAction Id="SetPropertyAppLogPathProperty"
BinaryKey="CustomActionDLL"
DllEntry="UpdateConfigurationsAction"
Execute="deferred"
Return="check"
Impersonate="no" />
<InstallExecuteSequence>
<Custom Action="SetPropertyAppLogPathId" Before="SetPropertyAppLogPathProperty"><![CDATA[NOT Installed]]></Custom>
<Custom Action="SetPropertyAppLogPathProperty" After="InstallFiles"></Custom>
</InstallExecuteSequence>
My Custom Action c# code
public class CustomActions
{
public static string ApplicationPath { get; private set; }
[CustomAction]
public static ActionResult UpdateConfigurationsAction(Session session)
{
try
{
session.Log("Begin UpdateConfigurationsAction");
ApplicationPath = session.CustomActionData["APPLICATIONLOG.PATHFORMAT"];
session.Log("Application Log Path is: " + ApplicationPath);
return ActionResult.Success;
}
catch (Exception e)
{
session.Log("Error in UpdateConfigurationsAction " + e.Message);
return ActionResult.Failure;
}
}
}
Issue Resolved
The issue was with the custom action. After making proper InstallExecuteSequence it worked!
Will update in solution section
Cross-Link: How to clean out broken uninstalls.
Microsoft FixIt: Before trying anything else, perhaps try the Microsoft FixIt tool to see if you can get rid of any
dangling installations. If unsuccessful check further down for other
approaches.
Debugging & Logging: Next fix your custom action in the package based on custom action debugging (I recommend the Advanced Installer MSI CA debugging video, it is quick and a good "hello debugger" session) and gathering logging information.
Countermeasure: Finally, maybe add a property to suppress the custom action from running as described here ("Adding Condition" section).
This is the simplest
idea I know of to suppress custom actions from running on uninstall - you just set the property involved when needed to suppress the custom action if it crashes. >
I would use it for all my custom actions - in fact - so I can suppress them all (or
maybe one by one) - especially for uninstall scenarios where you run into "catch 22" situations (unable to install, upgrade or uninstall due to custom action bugs).
Dangling Installations: In order to detect all related, dangling installations (if any), you can use this approach: Unable to uninstall program from WiX created MSI (enumerate all products with the same upgrade code).
I will add these links for now in case you find that dangling version:
wix - custom action dialogbox on silent uninstall of application
I screwed up, how can I uninstall my program?
When trying to remove an MSI which crashes on uninstall, the central question is how many computers are involved? If it is just one, then hacking the cached MSI database may be acceptable, otherwise you should create a patch package to fix the uninstall sequence and then trigger uninstall the normal way.
Links:
Throwing in one more link: WIX does not uninstall older version. It is possible to have installations per-user or per-machine.

How does the MSI Installer InstallValidate determine files in use?

I'm trying to work out how to prevent the Restart Manager from detecting that a restart is required when I uninstall my application.
My application has a Windows Service which uses a native DLL (Tanuki Wrapper) and creates another process (Java) which writes to some log files. I'm using WiX Toolset but I'm more interested in the MSI Installer itself. I've been trying some changes manually using Orca. For reference the relevant WiX configuration is (there are some other components for JARs etc that I have omitted):
<DirectoryRef Id="logs3327407xx">
<Component Guid="344ec345-bdd7-4c1d-801f-55ddf9e07735" Id="logs_wrapper_log88580873x">
<File DiskId="1" Id="fl_logs_wrapper_log88580873x" Name="wrapper.log" Source="logs\wrapper.log"/>
</Component>
</DirectoryRef>
<DirectoryRef Id="bin97543xxxx">
<Component Guid="67c93dd8-36ad-427f-9d79-64a07c719eea" Id="bin_wrapper_windows_x86_64_exe189026768">
<File DiskId="1" Id="fl_bin_wrapper_windows_x86_64_exe189026768" KeyPath="yes" Name="wrapper-windows-x86-64.exe" Source="bin\wrapper-windows-x86-64.exe"/>
<ServiceInstall Account="LocalSystem" Arguments="-s "..\conf\wrapper.conf" wrapper.console.flush=true" Description="My Example Service." DisplayName="My Service" ErrorControl="ignore" Id="srvc_i_bin_wrapper_windows_x86_64_exe189026768" Interactive="no" Name="MyService" Start="auto" Type="ownProcess" Vital="yes"/>
<ServiceControl Id="srvc_c_bin_wrapper_windows_x86_64_exe189026768" Name="MyService" Remove="uninstall" Start="install" Stop="both" Wait="yes"/>
</Component>
</DirectoryRef>
<DirectoryRef Id="bin_wrapper_native490235675">
<Component Guid="d7e4295a-1ce5-4dd2-aa92-230caac34247" Id="bin_wrapper_native_wrapper_windows_x86_64_dll156404367">
<File DiskId="1" Id="fl_bin_wrapper_native_wrapper_windows_x86_64_dll156404367" Name="wrapper-windows-x86-64.dll" Source="bin\wrapper\native\wrapper-windows-x86-64.dll"/>
</Component>
</DirectoryRef>
I understand that there is logic in the InstallValidate action that determines whether files are in use. It will either use the Restart Manager or the FilesInUse based on the MSIRESTARTMANAGERCONTROL property.
If I use the Restart Manager then it opens the dialog saying a restart is required. The logs say:
MSI (s) (1C:7C) [12:27:14:679]: Doing action: InstallValidate
Action ended 12:27:14: MigrateFeatureStates. Return value 0.
MSI (s) (1C:7C) [12:27:14:679]: PROPERTY CHANGE: Deleting MsiRestartManagerSessionKey property. Its current value is 'f2947dee632d694f8b4f1795ff254092'.
...
MSI (s) (1C:7C) [12:27:14:679]: Component: bin_wrapper_windows_x86_64_exe189026768; Installed: Local; Request: Absent; Action: Absent; Client State: Local
MSI (s) (1C:7C) [12:27:14:679]: Component: bin_wrapper_native_wrapper_windows_x86_64_dll156404367; Installed: Local; Request: Absent; Action: Absent; Client State: Local
MSI (s) (1C:7C) [12:27:14:679]: Component: logs_wrapper_log88580873x; Installed: Local; Request: Absent; Action: Absent; Client State: Local
...
MSI (s) (1C:7C) [12:27:14:741]: RESTART MANAGER: Detected that application with id 11368, friendly name 'java.exe', of type RmCritical and status 1 holds file[s] in use.
MSI (s) (1C:7C) [12:27:14:741]: RESTART MANAGER: Did detect that a critical application holds file[s] in use, so a reboot will be necessary.
MSI (s) (1C:7C) [12:27:14:741]: Note: 1: 1610
It doesn't actually say the files but if I disable the Restart Manager and use the FilesInUse instead then no dialog appears. This time the logs say:
Info 1603. The file C:\...\wrapper-windows-x86-64.exe is being held in use by the following process: Name: wrapper-windows-x86-64, Id: 11004, Window Title: '(not determined yet)'. Close that application and retry.
MSI (s) (1C:8C) [12:33:23:458]: 2 application(s) had been reported to have files in use.
Info 1603. The file C:\...\wrapper-windows-x86-64.dll is being held in use by the following process: Name: java, Id: 8284, Window Title: '(not determined yet)'. Close that application and retry.
MSI (s) (1C:8C) [12:33:23:458]: Note: 1: 2727 2:
MSI (c) (AC:28) [12:33:23:458]: File In Use: -wrapper-windows-x86-64- Window could not be found. Process ID: 11004
MSI (c) (AC:28) [12:33:23:458]: File In Use: -java- Window could not be found. Process ID: 8284
MSI (c) (AC:28) [12:33:23:458]: No window with title could be found for FilesInUse
Can someone please explain how the InstallValidate determines which files are in use?
Additionally how can I prevent the Restart Manager from saying that files are in use which will be released once the service is stopped?
As a side question, why is the Restart Manager not showing the MsiRMFilesInUse dialog? I have checked all the requirements on MsiRMFilesInUse Dialog and as far as I can tell they are all true.
I remember reading somewhere that using a ServiceControl rather than a custom action helps the Restart Manager know that those Files within that Component are used by the service. I have tried adding the files to that Component but it doesn't seem to make any difference.
The behavior of InstallValidate and in-use files related to ServiceControl isn't complicated. If there are files in use by a service and that service is in the ServiceControl table and marked to be stopped on uninstall then it will ignore those files as far as in-use behavior. Putting files in the same component makes no difference, and obviously Windows can't know that the service code is going to shut down processes that are causing files-in-use situations. To my knowledge there is no way of telling InstallValidate that some files really won't be in-use when they are due to be uninstalled.
You won't get an old-style FilesInUse dialog when Restart Manager isn't used because it requires an active window that the user can be prompted to close to shut down the app. This is the reason tray apps without an active window don't cause a FilesInUse dialog. I can't be sure, but it appears to me that the first log extract referring to Restart Manager actually IS RMFilesInUse, and I think that's the dialog you're seeing.
If the only files-in-use issues you're seeing are related to the java process that the service will shut down then a possible solution is:
Suppress all files-in-use dialogs during uninstall.
Use ServiceControl to shut down your service.
Ensure that your ServiceControl was Wait=1 and that it does not respond to the "stop service" request until the java process has been terminated, assuming you can explicitly shut it down.
Windows isn't so dumb that it will force a reboot just because files were in use at InstallValidate time but that isn't true at actual removal time. So the reboot won't be necessary if you can make sure that the files are no longer in use at the actual time they need removing/replacing/whatever. It's not unusual to see the dialog and then find that a reboot is not in fact necessary. So if you suppress the dialog and get everything shut down you won't see a reboot request.

Wix MSI fails when setting permissions on network path (util:PermissionEx)

I have an MSI that works perfectly when installing locally. If the data path is set to a network location, it fails.
Relevant LOG:
MSI (s) (BC:4C) [17:01:57:322]: Executing op: ActionStart(Name=ExecSecureObjects_64,,)
MSI (s) (BC:4C) [17:01:57:322]: Executing op: CustomActionSchedule(Action=ExecSecureObjects_64,ActionType=3073,Source=BinaryData,Target=ExecSecureObjects,CustomActionData=\\ravel\TeamData\lrieger\Tim2015Pre_Data\CreateFolderEveryone-1073741824C:\ProgramData\Nemetschek Engineering\TIM 2015.0.0.477590057-pre\CreateFolderEveryone-1073741824)
MSI (s) (BC:78) [17:01:57:324]: Invoking remote custom action. DLL: C:\Windows\Installer\MSIAEDE.tmp, Entrypoint: ExecSecureObjects
MSI (s) (BC:A8) [17:01:57:324]: Generating random cookie.
MSI (s) (BC:A8) [17:01:57:325]: Created Custom Action Server with PID 4488 (0x1188).
MSI (s) (BC:60) [17:01:57:335]: Running as a service.
MSI (s) (BC:60) [17:01:57:337]: Hello, I'm your 64bit Elevated custom action server.
ExecSecureObjects: Error 0x80070005: failed to get security info for object: \\ravel\TeamData\lrieger\Tim2015Pre_Data\
CustomAction ExecSecureObjects_64 returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox)
MSI (s) (BC:4C) [17:01:57:393]: Note: 1: 2265 2: 3: -2147287035
MSI (s) (BC:4C) [17:01:57:393]: User policy value 'DisableRollback' is 0
MSI (s) (BC:4C) [17:01:57:393]: Machine policy value 'DisableRollback' is 0
Action ended 17:01:57: InstallExecute. Return value 3.
WIX Code:
<Component Directory="DATA_DIRECTORY">
<RegistryValue Root="HKLM" Key="$(var.RegRoot)\Setup" Name="TIM_DATA_DIRECTORY" Value="0xff" Type="string" />
<CreateFolder>
<util:PermissionEx User="Everyone" GenericRead="yes" GenericWrite="yes" Domain="[LOGONDOMAIN]" />
</CreateFolder>
</Component>
Without the util:PermissionEx it works on the network share, but setting these permissions is a requirement, at least if the target directory is local.
Q: Is it possible to set permissions on a network location with wix/msi?
If Not, how can I detect that it is a network directory?
Or is there, in MSI, any way to mark a component as allowed to fail?
If it is not possible to do any of the above, I will probably need to write a custom action that tries to set the permissions but suppresses any failures...
Briefly, I don't think it's possible. The issue is that elevated custom actions run with the system account, and that account doesn't have any network privileges. That WiX utils code is already a custom action that's supplied as a helper for a common task, so writing your own custom action isn't going to help. If you run the CA not impersonated it won't run elevated (unless you elevate the entire MSI install at launch time) so that's not likely to help either. You need an elevated user app to do this for the network share, maybe run at first use of the app itself. This might help:
http://wixtoolset.org/documentation/manual/v3/howtos/ui_and_localization/run_program_after_install.html
I would assume it's a network share if it starts with \. A drive letter won't work with the CA anyway because drive letters are a user profile mapping (not a system mapping), so the system account won't know of them. In .Net, FileSystem.GetDriveInfo would help.

How to debug WiX installer

I am adding to build to your WiX installer to include a multi-website deployment based on custom dialog selection.
I am running into this issue when i run in debug mode and not sure how to tackle the problem to find what the issue is, I am getting a Failed to load XML Error:
MSI (s) (D0:60) [10:25:14:945]: Executing op:
ActionStart(Name=ExecXmlFile,,) Action 10:25:14: ExecXmlFile.
MSI (s) (D0:60) [10:25:14:960]: Executing op:
CustomActionSchedule(Action=ExecXmlFile,ActionType=3073,Source=BinaryData,Target=ExecXmlFile,CustomActionData=20C:\Program
Files\Company Name,
Inc\18.4.007\Navigator\bin\hibernate.cfg.xml30//property[#name='connection.connection_string_name']Workbench_PROD2130/
+ MORE SIMILAR STUFF
MSI (s) (D0:30) [10:25:14:976]: Invoking remote custom action. DLL:
C:\Windows\Installer\MSI5E32.tmp, Entrypoint: ExecXmlFile
MSI (s) (D0:B0) [10:25:14:976]: Generating random cookie.
MSI (s) (D0:B0) [10:25:14:976]: Created Custom Action Server with PID
3980 (0xF8C).
MSI (s) (D0:8C) [10:25:15:163]: Running as a service.
MSI (s) (D0:8C) [10:25:15:163]: Hello, I'm your 32bit Elevated custom
action server.
ExecXmlFile: Error 0x8007006e: failed to load XML file:
Since your error occurs when running a custom action, I would add a Debugger.Launch(); for C# or s.t. equivalent for other languages at the very start of your custom action method. This would allow you to debug in Visual Studio as usual.
The only advice I can give you is to use Orca, which is a low-level tool for creating and editing MSI file. At least it will validate your msi and show you any errors or warnings it finds.