How to prompt user for active processes and terminate them during uninstall - wix

I am using Wix 3.5 with such codes:
<util:CloseApplication Id="CloseMyApp" CloseMessage="yes" Target="Foo.exe" RebootPrompt="no"/>
<InstallExecuteSequence>
<Custom Action='WixCloseApplications' Before='InstallValidate' />
</InstallExecuteSequence>
It does really terminate the applications forcefully and silently before uninstall actually happens.
However, I want to know if it is possible to prompt users before such termination happens with a message box, and proceed termination if allowed?
Thanks

I think you are missing some references
Have a look at this question

Related

Wix: Executing installed exe as a first action on Uninstall

In my msi, I have to call the installed exe file with some parameters, as a very first action of uninstall. Here is the code:
<CustomAction Id="UnRegisterOnUninstallApplication"
Execute="immediate"
FileKey="MyProgram.exe" ExeCommand="/unregister" Return="asyncNoWait" />
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallInitialize"/>
<Custom Action="UnRegisterOnUninstallApplication" Before="UnpublishComponents" >Installed AND NOT UPGRADINGPRODUCTCODE</Custom>
</InstallExecuteSequence>
Although, it is scheduled Before UnpublishComponents, but issue is, at some computers, custom action is called during or after dependency dlls are uninstalled and so MyProgram.exe crashes here.
This is something seems unpredictable...
Can anyone please guide, if I'm missing something or doing something wrong???
Thanks a bunch.
There are several things incorrect here:
The design issue is that you shouldn't be running code to register or unregister. The recommended way is to capture the registry entries and add them as registry entries in the same component as that binary. Then it all just works.
Your custom action is asyncNoWait, and that means the uninstall continues while the program runs. If it takes a long time for some reason, or simply doesn't get enough of the processor, then yes, files may have been removed by the time it runs.
It's an immediate custom action, so it can run and start unregistering as the uninstall proceeds. However if the uninstall fails and rolls back the deleted registration will not be restored, so you'll end up with a broken product still installed, those registration entries will stay removed. It should be a deferred custom action and return = ignore or check, depending on whether you care if the program fails.
I might schedule the action before 'RemoveFiles' so that no dependent dlls have been removed before your custom action gets to run.

PerUser install with Custom Action - UAC disabled

I'm using WiX to generate an MSI that installs a browser plugin on a perUser basis. I have a custom action to install a driver using DPInst (which needs elevated privileges).
The install works fine when UAC is enabled; Windows shows the prompt to elevate. However, if I have UAC disabled and try to install on a regular user account, dpinst.exe will get spawned until the computer freezes. (About a thousand times at last count).
In the <InstallExecuteSequence> I have:
<Custom Action="Install_Drivers" After="InstallFiles">NOT Installed</Custom>
My custom action is:
<CustomAction Id='Install_Drivers' Execute='deferred' Directory='DRIVERS' ExeCommand='"[DRIVERS]DPinst.exe" /SW /SA' Return='ignore' Impersonate='no'/>
I have Return='ignore' because, from what I understand so far, dpinst.exe always returns a non-0 code.
How can I ensure that the custom action fails correctly when UAC is disabled? On a related note, can I show a custom message to the user when the driver installation fails?
Further Information: I'm developing on Windows 7 currently, but targeting WinXP and up.
Edit Taking a look at the log for the installation these seem to be the relevant lines:
Executing op: CacheSizeFlush(,)
Executing op: ActionStart(Name=Install_Drivers,,)
Executing op: CustomActionSchedule(Action=Install_Drivers,ActionType=3170,Source=C:\long_redacted\Drivers\,Target="C:\long_redacted_path\Drivers\DPinst.exe" /SW /SA,)
Disallowing shutdown. Shutdown counter: 0
CustomAction Install_Drivers returned actual error code 1073807364 but will be translated to success due to continue marking
The bit about the shutdown is, I believe, when I logged off stop the installation. (Canceling doesn't seem to have any effect).
Try setting the 'Impersonate=no' attribute on the 'CustomAction' element, like this:
<CustomAction Id='Install_Drivers' Execute='deferred' Directory='DRIVERS' ExeCommand='[DRIVERS]DPinst.exe" /SW /SA' Return='ignore' Impersonate="no" />
Also note: you have a stray double-quote in your ExeCommand
Installing a driver is an inherently per-machine operation. A limited user can't do it. So with UAC disabled, it's not going to work. DPInst apparently doesn't get the hint that it doesn't have permissions and can't get them. Sounds like a bug in DPInst. You should change your installer to be per-machine and add a launch condition on the Privileged property to prevent the installer from starting for limited users without UAC.

'wix execute batch before uninstall with administrator

My WiX XML file installs app that contains windows-service named OLOLO_SERVICE (for example). I want to stop this service when installing/reinstalling my app.
I use CustomAction with ExeCommand='sc stop OLOLO_SERVICE'.
<CustomAction Id='EnsureThatServiceIsStopped' Directory='INSTALLLOCATION'
Impersonate="no" Execute="immediate" ExeCommand="sc
stop OLOLO_SERVICE" Return="ignore" />
Inside <InstallExecuteSequence> tag is action
<Custom Action='EnsureThatServiceIsStopped' Before='InstallValidate' />
But this doesn't works, uninstaller shows this window "For uninstallation continue you should stop following executables" (maybe not 100% correct, because in my russian Windows 7 it is written in russian).
I think that possible reasons for this are
script runs before admin rights taken (and stopping service fails because it needs admin privilegies)
script runs after validation (and validation fails when checking installed executables)
Plesae help me, I want to stop service using batch 'sc stop OLOLO_SERVICE'
PS. I decided to simplify a question: I want my WiX to execute 'sc stop OLOLO_SERVICE' with administrator privilegies and before checking for running applications
You don't need to do this in a batch file, you can use the ServiceControl element:
<ServiceControl Id="ServiceControl_OloService"
Name="OLOLO_SERVICE"
Stop="both"
Remove="uninstall"
Wait="yes" />

Running a program on uninstall

I want to run a program when my software is being un-installed, it is a simple form that should gather some feedback on why people are un-installing my software.
I found some WiX examples that works to some degree.
It works pretty fine with a standard windows program (notepad), but when I try to run my own program, it does not work. I think the problems is that the program is removed, before it has been run.
I have tried to print the logs, but they did not give me any clues of what to do.
My code so far:
<CustomAction Id="LaunchFeedBackForm"
ExeCommand="notepad.exe" Directory="INSTALLDIR"
Return="asyncWait" >REMOVE="ALL"</CustomAction>
<InstallExecuteSequence>
<Custom Action="LaunchFeedBackForm" After="InstallValidate"/>
</InstallExecuteSequence>
So I need in some way the un-install process to halt or what ever, until the user has closed the feedback form. After the form has been closed, it should continue and remove all software including the feedback form program.
The way you'd like to get user's feedback seems not that natural to me. If I understand you correctly, you'd like to show this feedback form and wait while a user fills it in, and later on continue with uninstallation, right?
To my own experience, when a user decides to uninstall software, he/she would like it to get uninstalled as quickly and clear as possible. Bringing a "must fill" form in front of them would only negatively affect the user experience. Moreover, as you can see, it is more difficult from the technical point of view. I suppose you've also thought about passing this feedback on to your side, right? Is it emailing the info entered by user? How do you ensure the email gets sent?
Alternatively, you can have this form online on a certain web page of your site and start it when the uninstall is done (NOT in progress). In this way, you don't annoy the user blocking the uninstall process.
So, I would do the following:
have a custom action that starts a browser with a URL you need
the installation program SHOULD NOT WAIT for this to complete
BTW, do not expect lots of feedback - people rarely bother spending some time to give feedback :)
If your EXE is in the MSI, try using the FileKey attribute: http://wix.sourceforge.net/manual-wix2/wix_xsd_customaction.htm
For example, if your EXE is defined like this:
<File Id="FeedbackExe" Name="FeedbackExe.exe"/>
you can use:
<CustomAction Id="LaunchFeedBackForm"
FileKey="FeedbackExe" Execute="deferred"
Return="asyncWait">REMOVE="ALL"</CustomAction>
You can also try creating an uninstall log to see what happens with the custom action:
msiexec.exe /x <ProductCode> /L*V "C:\uninstall.log"
where you use your actual ProductCode.
So I need in some way the un-install process to halt or what ever,
until the user has closed the feedback form. After the form has been
closed, it should continue and remove all software including the
feedback form program.
To do this one would set After="InstallValidate"
<InstallExecuteSequence>
<Custom Action="InstallCustomLogic" After="InstallFinalize" />
<Custom Action="UninstallCustomLogic"
After="InstallValidate" >
NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")
</Custom>
</InstallExecuteSequence>
Set Return attribute to check so that the installer will halt until the specified executable returns.
<CustomAction Id="UninstallCustomLogic"
Directory="INSTALLFOLDER"
ExeCommand="[INSTALLFOLDER]\RetailConnectCustomLogic.exe uninstall"
Return="check"
/>
This is useful in the event where you need to run something located in the program directory before uninstalling the program. One could also set the attribute to ignore if it doesn't return 0

WiX uninstall - close application before Restart Manager

I have an installer done with WiX. When it's done installing, it starts an application that injects some code in the Explorer process.
Currently when I uninstall, the Restart Manager kicks in and offers to shut down my application and Explorer. Instead of that I want to close my application manually (this is done by running it again with -exit on the command line). I have a custom action that does it.
Here's what I tried so far:
<CustomAction ExeCommand="-exit" FileKey="MyApp.exe" Id="CloseMyApp" Impersonate="yes" Return="ignore" />
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallInitialize" />
<Custom Action="CloseMyApp" Before="RemoveFiles" />
</InstallExecuteSequence>
This doesn't work. The action is done way after the Restart Manager session. So the Restart Manager pops up and asks to close my app and Explorer. The action runs later, but by then the app is already gone.
So then I tried this:
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallInitialize" />
<Custom Action="CloseMyApp" Before="RemoveExistingProducts" />
</InstallExecuteSequence>
This also doesn't work. The action is done too late still. I also get "warning LGHT1076 : ICE63: Some action falls between InstallInitialize and RemoveExistingProducts.".
So basically - how do I execute my custom action during uninstall and before the Restart Manager session?
I'm guessing if I use Impersonate="no" it might run at the right time, however that's not an option. That's because the new process must run for the same user as the process that has to close because it looks up its window and sends messages. That's much trickier to do if the processes belong to different users.
Any ideas?
You would need the CloseMyApp custom action to run before InstallValidate since that is when the restart manager is processed (doc). Alternatively, you could disable restart manager with MSIDISABLERMRESTART or MSIRESTARTMANAGERCONTROL Properties.