Wixtoolset - lock appears after installing - wix

I made an msi with wixtoolset and I give permissions to the installed files to all users with the code below. The problem is that after installing, all the files on the screen appear with a lock on them. I still have permission to access them but I would like to avoid the lock thing.
My Wix version is 3.5
I know the problem is with the permissions I give because when I remove them from the instakker, the lock does not appear.
<DirectoryRef Id="INSTALLFOLDERSERVICE">
<!-- SERVICE FILES -->
<!-- Create a single component which is the TestService.exe file -->
<Component Id="SERVICE" GUID="*">
<!-- Remove all files from the INSTALLFOLDER on uninstall -->
<RemoveFile Id="ALLFILES" Name="*.*" On="both" />
<!-- Tell WiX to install the Service -->
<ServiceInstall Id="ServiceInstaller"
Type="ownProcess"
Name="SERVICEtoINSTALL"
DisplayName="$(var.Name)"
Description=""
Start="auto"
ErrorControl="normal" />
<!-- Tell WiX to start the Service -->
<ServiceControl Id="StartService" Start="install" Stop="both" Remove="uninstall" Name="SERVICEtoINSTALL" Wait="yes" />
<CreateFolder>
<Permission User="Everyone" GenericAll="yes" />
</CreateFolder>
</Component>
the code compiles perfectlly. I need that permissions to manage the files from other app but I would like to avoid the lock thing.
You can see it here;
https://drive.google.com/open?id=1Z6zYEt444DjOXe2ODP60q2X00Xpq5bkZ
Thank you!!

I found the solution! The problem was that I was giving permissions to folder of the shortcut on Desktop, removing that permission tag solved my problem!

Related

Wix: Installer slow because file in use

I use wix toolset to install an ASP.NET Core application as a windows service. When doing a major upgrade, the installer can take very long (5 mins) while it usually is a couple of seconds. This is because the InstallValidate action gives errors because files are in use by the service, I noticed that if I stop the service before starting the installer, it always runs smoothly. I use the following code to install and start/stop the service: (this is generated using heat)
<Component Id="ApiEndpoint.exe" Guid="*">
<File Id="ApiEndpoint.exe" KeyPath="yes" Source="$(var.publishDir)\ApiEndpoint.exe" />
<wix:ServiceInstall Id="ApiEndpointInstall" DisplayName="ApiEndpoint" Name="ApiEndpoint" ErrorControl="normal" Start="auto" Type="ownProcess" Vital="yes" xmlns:wix="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<util:ServiceConfig RestartServiceDelayInSeconds="60" ResetPeriodInDay="1" FirstFailureActionType="restart" SecondFailureActionType="restart" ThirdFailureActionType="restart" />
</wix:ServiceInstall>
<wix:ServiceControl Id="ApiEndpointControl" Name="ApiEndpoint" Start="install" Stop="both" Remove="uninstall" xmlns:wix="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" />
</Component>
Shouldn't the files in use by the ApiEndpoint be excluded because the service will be stopped anyway? Is there a way I can stop the service before the InstallValidate, I tried this with a custom action, but this wasn't possible because no admin privileges are present at that point.
I also tried to ignore the exe file from heat and make a component for it myself, like below, this results in the same issue.
<Fragment xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<ComponentGroup Id="ExeComponents" Directory="INSTALLFOLDER">
<Component Win64="yes" Id="ExeComponent" Guid="*">
<File Id="ExecFile" Source="$(exeSource)" KeyPath="yes" />
<ServiceInstall Id="ApiEndpointInstall" DisplayName="ApiEndpoint" Name="ApiEndpoint" ErrorControl="normal" Start="auto" Type="ownProcess" Vital="yes">
<util:ServiceConfig RestartServiceDelayInSeconds='60' ResetPeriodInDays='1' FirstFailureActionType='restart' SecondFailureActionType='restart' ThirdFailureActionType='restart' />
<util:PermissionEx
User="Everyone"
GenericAll="yes"
ServiceChangeConfig="yes"
ServiceEnumerateDependents="yes"
ChangePermission="yes"
ServiceInterrogate="yes"
ServicePauseContinue="yes"
ServiceQueryConfig="yes"
ServiceQueryStatus="yes"
ServiceStart="yes"
ServiceStop="yes" />
</ServiceInstall>
<ServiceControl Id="ApiEndpointControl" Name="ApiEndpoint" Start="install" Stop="both" Remove="uninstall" />
</Component>
</ComponentGroup>
</Fragment>
I'm very new at wix so I'm not sure if I'm missing something obvious or if this is just a limit of Wix.
I can see that the service stops eventually when the files are being copied, but it just seems like it is stopped either too late, or the installer should ignore the files in use by the service that will be stopped anyway.

Using wix to install a windows service that may already be installed

I'm using WiX 3.1.1 to install an exe and a service. Sometimes, the MSI install fails with a fairly generic error:
Error 1923. Service 'MyService' (MyService) could not be installed.
Verify that you have sufficient privileges to install system services.
Experimentally, this appears to be because the service already exists, and my xml uses Vital="yes"
I would like to have the MSI ensure the service is installed, but accept (or repair) it if it's already present. It sounds like I should set Vital="no", will this cause it to ignore other errors? Is there a way to limit what kind of errors are ignored? Is there a best practice I'm missing?
For reference, a redacted snippet of my xml:
<Component Id="REDACTED" Guid="{REDACTED}" Win64="yes">
<File
Id="filB754EE270009E240193A8279D1529A43"
Name="myservice.exe"
KeyPath="yes"
DiskId="1"
Source="SourceDir\File\filB754EE270009E240193A8279D1529A43" />
<ServiceControl
Id="MyService"
Name="MyService"
Start="install"
Stop="both"
Remove="uninstall"
Wait="no" />
<ServiceInstall
Id="MyService"
Name="MyService"
Type="ownProcess"
Start="auto"
ErrorControl="normal"
Vital="yes"
Account="[SERVICEACCOUNT]"
Arguments="svc -config "C:\Program Files\MyService\conf\service.flags""
Description="My Service">
<ServiceConfig
ServiceName="MyService"
FirstFailureActionType="restart"
SecondFailureActionType="restart"
ThirdFailureActionType="restart"
ResetPeriodInDays="1"
RestartServiceDelayInSeconds="5"
xmlns="http://schemas.microsoft.com/wix/UtilExtension" />
</ServiceInstall>
</Component>

Wix File property with user selected directory

I am trying to install a windows service using wix but I can't seem to point the file for the service to the user selected install directory.
<Component Id="MyServiceInstaller_ServiceControl" Guid="B72CAA3F-F2DB-48D2-90DD-061209AB2CE5" Directory="INSTALLDIR">
<CreateFolder />
<File Id='MyServiceEXE' Name='MyService.exe' DiskId='1' Source='[INSTALLDIR]MyService.exe' KeyPath='yes'/>
<ServiceInstall Id="MyServiceInstaller_ServiceInstall"
Type="ownProcess"
Vital="yes"
Name="My Service"
DisplayName="My Service"
Description="This will make windows services great again!"
Start="auto"
Account="NT AUTHORITY\LocalService"
ErrorControl="ignore"
Interactive="no" />
<ServiceControl Id="MyServiceInstaller_ServiceInstall"
Name="My Service"
Stop="both"
Remove="uninstall"
Wait="yes" />
</Component>
The issue seems to be when I use any [PROPERTY] directory I get the following error.
error LGHT0103 : The system cannot find the file
'[INSTALLDIR]MyService.exe'.
How do I tell Wix to use the installation folder the user selected as the path for the service?
File/#Source points to the file in your build environment. Component/#Directory tells Windows Installer where the file should be installed. That controls the file used to install and control the service.

How do you reference a file from within a heat.exe generated harvest from elsewhere in a WiX installer?

I've written a new installer using the WiX Toolset. It appears that the best practice is to use the heat.exe application to run through your built application files and auto-generate references for inclusion in your installer. This is great and all, but I find that by using this technique you pretty much block those files from being usefully in ANYTHING else except the act of copying them to the install directory. This is because I can't seem to "reference" these files for other things. For example. One of the files I would like to install as a service, but the ServiceInstall mechanism doesn't seem to let you use something referenced out of the harvest. Also, one of my files is an XML file that I would like to modify based on input from the user during install. Again, I can't seem to reference this file out of the harvest for use in the XmlConfig mechanism.
I've seen this post, but the chosen answer doesn't actually provide an example. And to boot, the WiX compiler does not let you put '#' symbols in the identifier field because it is "not a legal identifier" as the answer post claims. And if you use the plain IDs out of the harvest, it complains that they already exist.
Here is a snippet out my harvest .wxs file.
<!-- Xml file I'd like to modify during install -->
<Component Id="cmp78CF3591818BB6F883096F2C98654BA9" Guid="*">
<File Id="fil1532F0BC6EDCE81B25489D872A72339A" KeyPath="yes" Source="$(var.MyApplication.TargetDir)\log.config" />
</Component>
<!-- ... -->
<!-- Application I'd like to install as a service -->
<Component Id="cmp84F0EA671F93094E33AE84FA2A03BA2E" Guid="*">
<File Id="filD4A27A27D20D3D734B279B4F21754836" KeyPath="yes" Source="$(var.MyApplication.TargetDir)\MyService.exe" />
</Component>
For the service install, I feel like the intuitive way would be something like this:
<Component Id="cmp84F0EA671F93094E33AE84FA2A03BA2E">
<File Id="filD4A27A27D20D3D734B279B4F21754836" />
<ServiceInstall
Id="MyServiceID"
Name="MyService"
Type="ownProcess"
Start="auto"
ErrorControl="normal"
Interactive="no">
</ServiceInstall>
<ServiceControl Name="MyService" Id="MyServiceControl" Start="install" Stop="both" Remove="uninstall" Wait="yes"/>
</Component>
But of course this does not work because it claims the IDs are duplicated. Which I guess they are, but how can I say "You know that file 'X' inside the harvest... ya, I'd like to install that as a service." I have been able to get the install to work, but I had to filter MyService.exe out of the harvest and manually added it. Now if that is the case every time you'd actually like to do something with a particular file, then I think I may just forgot using the stupid heat.exe technique and manually input every file. So what exactly is the syntax that you would use to reference files from inside the heat.exe harvest?
Simplest answer: Don't use Heat.exe to generate authoring for files that require special handling, like services. Exclude those files from harvesting (using a staging directory if necessary).
Heat has generated component definitions for you. Put the ServiceInstall element inside the component in harvest.wxs. Your new snippet would look like this:
<!-- Application I'd like to install as a service -->
<Component Id="cmp84F0EA671F93094E33AE84FA2A03BA2E" Guid="*">
<File Id="filD4A27A27D20D3D734B279B4F21754836" KeyPath="yes" Source="$(var.MyApplication.TargetDir)\MyService.exe" />
<ServiceInstall
Id="MyServiceID"
Name="MyService"
Type="ownProcess"
Start="auto"
ErrorControl="normal"
Interactive="no">
</ServiceInstall>
<ServiceControl Name="MyService" Id="MyServiceControl" Start="install" Stop="both" Remove="uninstall" Wait="yes"/>
</Component>

How to wait for a file being installed to GAC before installing a service with wix

I'm using Wix to create my application installer and using it to install an assembly in the GAC and it works fine.
My issue is when I'm setting the assembly property 'copy local=false' and I'm executing the installation, then my services is not being installed cause it can't find this dll in the local folder and it's not being installed to GAC yet.
If I'll install another component from the EXE installation and will verify that the DLL is in the GAC I will be able then to install the service.
I'm using Paraffin.exe to go all over my application directory and generate a wix file and also using Mold file to add component not from this directory.
<DirectoryRef Id="Manager">
<Component Id="NlogGACRegisterComponent" Guid="1B224CD1-6EE8-46D3-9335-A84B7D8FB87B">
<File Id="NlogDLL" Name="Nlog.DLL" Source="..\Logging\Nlog.DLL" KeyPath="yes" Vital="yes" Assembly=".net"/>
</Component>
<Component Id="ManagerServiceComponent" Guid="EA31E161-4331-4A82-8F2B-7E26F62C96D6">
<File Id="StateManagerServiceEXE" Name="ManagerHostService.exe" DiskId="1" Source="..\ManagerHostService.exe" KeyPath="yes" Vital="yes" />
<ServiceInstall Id="ServiceInstaller" Type="ownProcess" Name="ManagerHostService" DisplayName="Manager Service" Description="Manager Service" Start="auto" Account="[SERVICEACCOUNT]" Password="[SERVICEPASSWORD]" ErrorControl="normal">
<util:PermissionEx User="Everyone" GenericAll="yes" ServiceChangeConfig="yes" ServiceEnumerateDependents="yes" ChangePermission="yes" ServiceInterrogate="yes" ServicePauseContinue="yes" ServiceQueryConfig="yes" ServiceQueryStatus="yes" ServiceStart="yes" ServiceStop="yes" />
</ServiceInstall>
<ServiceControl Id="StartService" Start="install" Name="ManagerHostService" Stop="both" Remove="uninstall" Wait="yes" />
</Component>
</DirectoryRef>
This in the Mold file which responsible to install the DLL to GAC and then the service.
How can I make sure it first install the DLL's and then the service?
All files and Dlls ARE installed by the time that services are started. Look in your MSI file with Orca at the InstallExecuteSequence (or look in a verbose log) and you'll see that InstallServices and StartServices are after InstallFiles.
The issue is that assemblies aren't installed and available in the GAC until InstallFinalize, this is described here:
https://msdn.microsoft.com/en-us/library/aa370063(v=vs.85).aspx
where it says "This means you cannot use the ServiceControl Table to start the service, instead you must use a custom action that is sequenced after InstallFinalize." which is what you'll need to do.