I have this app, its an MSI app using WIX toolset. I faced an issue where when deployed using certain third party software, for example, COMODO one ADDT tool on windows server 2012 R2, where the app will not launch after install. The WIX config is configured to launch an executable after installing via a CustomAction.
I'm aware of "Impersonate=yes", however, Apparently when deploying the MSI, the SYSTEM user account is used which prevents the " Impersonate=yes " from working correctly.
This is how the app is being launched:
<Property Id="WixShellExecTarget" Value="[#appEXE]" />
<CustomAction Id="LaunchApplication" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes" />
<InstallExecuteSequence>
<Custom Action="LaunchApplication" After='InstallFinalize'>NOT Installed</Custom>
</InstallExecuteSequence>
Thus the question is, is it possible to launch a "CustomAction" as the logged on user when the MSI is run from the SYSTEM user account?
The impersonate attribute is only going to have an effect for deferred custom actions. Impersonate Yes means run as the user who launched the installer and No means run as SYSTEM.
Custom actions scheduled for immediate execution (outside of the InstallInitialize..InstallFinalize block) are always going to run as the user who launched the installer.
While I'm not familiar with ADDT tool I can say that other software distribution tools such as Microsoft SCCM Server will typically launch the installer as SYSTEM so none of these ends up mattering that much. Impersonate or not you'd be running as SYSTEM.
In these scenarios it doesn't make sense to launch the application at the end of the install. You aren't in the users desktop context and no UI is possible anyways.
Related
i have got an WIX installer with following package information
<Package InstallerVersion="200"
InstallScope="perMachine"
Compressed="yes"
Description="$(var.ProductName)"
Manufacturer="$(var.ProductManufacturer)"
InstallPrivileges="elevated"
Platform="$(var.Platform)"/>
This lead to this situation
After clicking "Installieren" UAC comes up and asks for administrator rights which is correct.
Within this installer i have to run a custom action for installing a explorer shellextension
<CustomAction Id="RegisterShellExtension"
Directory="INSTALLDIR"
ExeCommand='[INSTALLDIR]RegShell.exe --mode register --restartExplorer --path "[INSTALLDIR]$(var.ProductName)ShellExtension.dll"'
Impersonate="no"
Execute="deferred"
Return="ignore">NOT VersionNT64</CustomAction>
<Custom Action="RegisterShellExtensionx" After="InstallFinalize">(NOT VersionNT64) AND (NOT Installed)</Custom>
In the manifest of RegShell.exe adminstrator rights are requested
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
This leads to the situation that the UAC asks for administrator rights again.
Is it possible that only one time UAC is raised instead of two times?
WiX isn't calling UAC twice, your custom actions are. CA's have to be scheduled prior to InstallFinalize to run deferred. Do this with the no impersonation and they should already be running elevated as SYSTEM so therefore no UAC prompts.
BTW I should mention that these self registration custom actions are an antipattern as they can't be rolled back if they fail and can fail and break the installer. Normally we use registry entries to configure explorer.
For example, your condition is Not VersionNT64. You might want to add and Not REMOVE="ALL" otherwise the CA will try to fire during uninstall and fail. Oh wait, nevermind... you set Return="ignore" so if it ever does fail you'll sweep it under the rug and not know there is a problem.
https://learn.microsoft.com/en-us/windows/win32/shell/reg-shell-exts
Finally, I see you are using WiX v4 (Package element instead of Product element.) You should be aware that isn't a final GA and shouldn't be used for production installers.
Our installer currently "installs" a windows service exe i.e. it just copies the file on to the users PC, but doesn't start it.
Then when our app is run, it will "install" the service many times using InstallUtil and each instance of the service will have a different service name.
So when we come to upgrade our app, we have no idea how many of these services are running and what they are called - but we do know that their service name will start with "ABCService_".
So, I created a couple of VB.NET custom actions - one called "stopServices" and one called "startServices". The first one will scan the user's PC for any windows service that starts with "ABCService_" and store its name in an XML file in the temp folder along with an attribute stating whether the service was running or not. It will then stop each of the running services.
Then the normal installation would continue - the windows service exe will be upgraded etc
The second custom action, will do the opposite - it will read the xml file and start any service that was originally running.
Now in theory (in my mind) this should work - but the problem I have is where to place these custom actions within the wix msi code. I've currently got them as:
<InstallExecuteSequence>
<Custom Action="CA_StopWindowsServices"
After="InstallInitialize" />
<Custom Action="CA_StartWindowsServices"
Before="InstallServices">
<![CDATA[NOT Installed]]>
</Custom>
</InstallExecuteSequence>
Because the custom actions alter the state of the PC, they have to be placed in the InstallExecuteSequence and Visual Studio tells me that the Stop action has to be after InstallInitialize and I thought having the start one before InstallServices might be a good place !?
BUT - this is my problem - when I run the msi; Windows complains that one of the files that needs to be upgraded (which is the windows service exe) is in use by how many instances of the service are running - which I knew would be a problem and hence why I wrote the custom actions; but I don't seem to be able to call the one that stops them before windows complains that they are in use ?!
Just thought that knowing how I defined the custom actions, might be relevent:
<CustomAction
Id="CA_StopWindowsServices"
BinaryKey="CustomActionDLL"
DllEntry="CustomActionStopServices"
Execute="deferred"
Return="check" />
<CustomAction
Id="CA_StartWindowsServices"
BinaryKey="CustomActionDLL"
DllEntry="CustomActionStartServices"
Execute="commit"
Return="check" />
Now saying all of that - I just ran my msi & when windows complained that 2 service instances were using files that needed to be replaced - I chose the first option, which is for windows to close them down and start them up at the end - which is basically what I'm trying to do :) So another question is - is it possible for me to tell windows to do this automatically - without it asking the user ? If it helps, the msi is actually run from a burn bootsrapper.
Many thanks in advance.
Cheers,
Big Chris.
Windows installer checks if files that will be replaced are in use during InstallValidate which happens before the InstallExecute sequence.
The problem is that you need elevation to stop the services which you don't have if you schedule a custom action before InstallValidate (usually).
In a bootstrapper, however, you can schedule tasks to stop the services before InstallValidate because the MSI always runs elevated from the elevated bootstrapper process that starts when you click install.
I haven't checked but adding a <ServiceControl> for the services in the MSI may automatically stop the services during the "StopServices" standard action and also avoid the FilesInUse dialog from InstallValidate. I haven't gotten around to testing this though since I already have a working solution with the bootstrapper.
So try your custom action solution but schedule your custom action to stop the services before InstallValidate.
I've just had to jump through hoops to get my application to install on Windows 8.1 and I'm concerned for my users. I'm testing the installer inside Parallels on my macbook.
First of all I had to disable SmartScreen as this just completely borked everything and wouldn't allow the installer to run at all. I'm not really happy to just tell my users to turn this off as that doesn't really make much sense.
After I jumped through that hoop Windows wouldn't allow my installer to access the C:\Program Files(x86)\ directory without administration rights. I have only one user on the machine that is in the administrators group and I was running the installer through that account.
There also wasn't a Run as Admin option in the context menu so I had to open a Command Prompt as Administrator and issue the following command:
net user administrator /active:yes
Then reboot the machine.
Since I'm a one man band operation making a free app I'm seriously short on beta testers and I can't justify getting an EV certificate to sign the installer with etc.
Seems making / distributing apps for Windows is getting harder and also trashing the user experience in the process.
What are the real options to make things better for my users?
The installer technology is WiX and I already set the following in the installer:
<Property Id="MSIUSEREALADMINDETECTION" Value="1" />
In the Product element I also already set the following:
InstallScope="perMachine"
InstallPrivileges="elevated"
Applications must be run with administrator privileges. How to ask the user is? How to verify that he agreed to? How do I know whether already running application as an administrator?
Made as described here by the user ChrisW67. The result is not received. If possible, give an example of "Hello world" project.
P.S Windows 7. Am writing in Qt Creator. Qt5.2
Disclaimer: Why does your application require admin rights? A modern application should in most cases be able to avoid this. One could use a service for the elevated actions.
I realize that you are using Qt. I don't have access to this tool at the moment, but here are a few general options. Essentially you need to modify the manifest that gets embedded into the binary on compilation:
.NET:
How do I force my .NET application to run as administrator? (as stated above; you modify the manifest that gets embedded in your application executable). More here.
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
Remember to verify admin rights in case the UAC is disabled - in that case the user is not prompted for admin rights on application launch.
C++: In C++ you can set a flag in the project properties: How to run application with Admin privileges using Manifest file in Visual Studio 2005?
Shortcut: You can set up the launching shortcut to require admin rights. The user will then be prompted on launch. "Run this program as an Administrator".
I have a set of NetTCP services configured that run under a Windows service for production but I use a console app to spin them up for debugging purposes. With Windows Vista I disabled UAC outright because it was annoying, however I'm trying to leave it enabled with 7 because it does everything I want while being very quiet and not naggy.
The issue I ran into is when running VS in "standard" mode (i.e. not using run as administrator) the services won't spin up because it says this:
"The service endpoint failed to listen on the URI 'net.tcp://localhost:60000/[ServiceName]' because access was denied. Verify that the current user is granted access in the appropriate allowedAccounts section of SMSvcHost.exe.config."
After a bit of research I was able to find this file and modify it with the SID for my user account. The config looks like this:
<?xml version="1.0" encoding="utf-8"?><configuration>
<runtime>
<gcConcurrent enabled="false" />
<generatePublisherEvidence enabled="false" />
</runtime>
<system.serviceModel.activation>
<net.tcp listenBacklog="10" maxPendingConnections="100" maxPendingAccepts="2" receiveTimeout="00:00:10" teredoEnabled="false">
<allowAccounts>
<add securityIdentifier="S-1-5-21-XXXXXXX"/>
</allowAccounts>
</net.tcp>
<net.pipe maxPendingConnections="100" maxPendingAccepts="2" receiveTimeout="00:00:10">
<allowAccounts>
<add securityIdentifier="S-1-5-21-XXXXXXX"/>
</allowAccounts>
</net.pipe>
<diagnostics performanceCountersEnabled="true" />
</system.serviceModel.activation></configuration>
The SID came from the tool packaged in the Sysinternals suite and was validated against ADSI Edit so I know it's correct. After a reboot the services still won't spin up though and I'm trying to avoid forcing it to run in administrative mode because then you can't double-click on solution or project files anymore which is rather irritating.
Anyone have any ideas? The SMSvcHost.exe.config file came from "C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation" and even though I'm running x64 the app is compiled in x86 mode. I'm not sure if that is where my trouble lies?
To find "right" configuration file location do the following:
Locate NetTcpPortSharing in serivce tab in Task Manager.
Click Go to process in context menu.
Click Open file location.
ps.
on my Windows 2008 R2 x64 with .NET 4 location is C:\Windows\Microsoft.NET\Framework64\v4.0.30319