wixtoolset / issues

WiX Toolset Issues Tracker
http://wixtoolset.org/
130 stars 24 forks source link

Files-In-Use checking does not work with dynamic names #8616

Closed PaulGlynn588 closed 3 months ago

PaulGlynn588 commented 4 months ago

WiX Version

5.0.0

.NET or MSBuild or Visual Studio Version

.NET 4.8 / VS 2022 17.10.1

HeatWave Version

1.0.4.5

Windows Version

Win 11 21H2

Repro Repo

No response

Repro Steps

We have a service that is installed as part of a multi-instance install. The service is defined as:

    <DirectoryRef Id="SVCDIR" FileSource="$(var.ServiceBinDir)">

      <Files Include="*.dll" />
      <Files Include="ConnectService.exe.config" />

      <Component Id="ServiceComponent" Guid="A0F2D919-BE84-4FFC-AB02-E0C6507B9100" MultiInstance="yes">

        <File Id="ConnectService.exe" Name="ConnectService.exe" KeyPath="yes" />

        <ServiceInstall Id="InstallConnectAgent" Name="ConnectAgent$[INSTANCENAME]" DisplayName="Connect Agent [INSTANCENAME]" Type="shareProcess" Account="NT AUTHORITY\NetworkService" Start="auto" ErrorControl="normal">

        <ServiceControl Id="ControlConnectAgent" Name="ConnectAgent$[INSTANCENAME]" Start="install" Stop="both" Remove="uninstall" />
      </Component>

    </DirectoryRef>

As the install is multi-instance each installed service gets a different name based on the instance name.

On upgrade the Files-In-Use checking should detect the service has a service control action that will stop the service and no Files-In-Use dialog should be displayed.

It doesn't detect this correctly. It seems the logic finds the running service is locking files and the tries to find a record in the ServiceControl table that for the service to see if it will be stopped.

Problem is the running service might be called say "ConnectAgent$MediaStore" while the record in ServiceControl table says "ConnectAgent$[INSTANCENAME]". Seems it is just trying to find an exact match and not taking into consideration the name may need to be resolved first.

Actual Result

Displays the Files-In-Use dialog

Expected Result

Not to display the Files-In-Use dialog (as the service will be shut down by service control)

Acknowledgements

bevanweiss commented 4 months ago

This behaviour I believe is entirely Windows Installer. https://stackoverflow.com/questions/33248658/how-does-the-msi-installer-installvalidate-determine-files-in-use https://learn.microsoft.com/en-au/windows/win32/msi/servicecontrol-table?redirectedfrom=MSDN

I don't think you can re-schedule ServiceConfig to be before InstallValidate (where the files are checked for being in use, and ServiceConfig table is consulted for exemptions). You could potentially do some crazy stuff just before InstallValidate and add some temporary ServiceConfig records that precisely match your in-use Service elements... that might do the job. But it sounds like quite a lot of effort.

It's a use case that probably wouldn't be exciting to support for any of the WiX developers. So it's likely you'd need to construct the solution yourself, or fund the likes of Rob / Bob to develop it for you (www.firegiant.com).

PaulGlynn588 commented 4 months ago

OK Thanks. Updating the ServiceControl records before InstallValidate seems to do the trick:

var database = session.Database;

using (var view = database.OpenView(database.Tables["ServiceControl"].SqlSelectString))
{
    view.Execute();

    Record record;

    while ((record = view.Fetch()) != null)
    {
        view.Modify(ViewModifyMode.Delete, record);

        var value = record.GetString("Name").Replace("[INSTANCENAME]", session["INSTANCENAME"]);

        record.SetString("Name", value);

        view.Modify(ViewModifyMode.InsertTemporary, record);
    }
}
bevanweiss commented 4 months ago

I'm unsure that such a 'hack' would be desired within the core WiX toolset.. so I don't think this issue should remain open (although Rob / Bob could decide that at triage).

You could try to raise the issue with Microsoft directly. https://learn.microsoft.com/en-au/windows/win32/msi/windows-installer-portal The Windows Installer framework itself doesn't appear to be expanding the formatted fields for the ServiceControl during the InstallValidate checks. I'm not sure that they would action this particular problem though...

barnson commented 3 months ago

The Name column is formatted, so I'd expect it to work but maybe MSI doesn't actually format the value? That would have to be a bug fix in MSI.