We have a scenario where we are trying to perform a major upgrade without
removing the user's data files and configuration. If we sequence
RemoveExistingProducts just before InstallInitialize or just after
InstallInitialize, the old version gets uninstalled and all of the settings
and configuration files are deleted.
If we sequence RemoveExistingProducts between InstallExecute and
InstallFinalize, the user settings are kept intact but the new version of our
Windows service is started *before* the old version is uninstalled. Our
service depends on plugins, and this has the unfortunate effect of loading
*both* the new plugins and the old ones at the same time! Not only that, the
old plugins get deleted out from under the service when the "commit" takes
place.
What are the best practices in this case - rewriting the entire service with
a different plugin loader isn't an option :)
Otherwise I think you'd have to give up on the ServiceControl table and have
a custom action start your newly-installed service after
RemoveExistingProducts in a Commit custom action if you have the GAC
problem, but that's not exactly ideal.
--
Phil Wilson
The Definitive Guide to Windows Installer
http://www.apress.com/book/view/1590592972
"ShadowChaser" <Shadow...@discussions.microsoft.com> wrote in message
news:2407AFB3-B76D-4C76...@microsoft.com...
The plugins are loaded based on filename, unfortunately. The original design
made the filenames the same as the CLSIDs of the COM objects they host. The
server startup code lists the filenames and creates the COM objects. In the
case of the upgrade, the old plugin DLLs are still in the directory and
registered at the time the upgraded service starts.
There might be a case I'm missing though - I'm infering the behavior based
on the MSI installation logs and our service startup logs showing 4 plugins
loading instead of 3. When I look at the plugin directory, I see three files.
Everything seems to point to the fact the old plugins exist on disk in their
original names and are still registered.
What exactly does "registered" mean? Is this COM? And you're sure there is
nothing in the GAC? There are definitely issues if you do an upgrade and
register COM assemblies in the GAC because of that darn behavior of
assemblies not being available in the GAC until Commit time, because you've
written a whoile bunch of registry entries referring to an assembly in the
GAC that is not in fact there yet.
--
Phil Wilson
The Definitive Guide to Windows Installer
http://www.apress.com/book/view/1590592972
"ShadowChaser" <Shadow...@discussions.microsoft.com> wrote in message
news:4C5CAE7F-35E3-41B5...@microsoft.com...
MSI (s) (AC:A4) [13:09:19:792]: Doing action: StartServices
MSI (s) (AC:A4) [13:09:19:800]: Doing action: InstallExecute
MSI (s) (AC:A4) [13:09:23:896]: Executing op: ServiceControl(,Name=<our
service name>,Action=1,Wait=1,)
Action start 13:09:25: RemoveExistingProducts.
MSI (s) (AC:88) [13:09:29:183]: Executing op: FileRemove(,FileName=<removed
plugin>.dll,,ComponentId={DB87FB19-3555-43DE-87B9-39C02833DD5C})
We have InstallExecute sequenced at 6500, RemoveExistingProducts sequenced
at 6501, and InstallFinalize at 6600.
The InstallExecute block includes all of the "new install" actions including
"StartServices", while the old plugin removal happens in
RemoveExistingProducts. Idealy MSI would let us schedule
RemoveExistingProducts "in" the InstallExecute block.
Looks like a custom action is the only choice? :(
Vijay
> I opened up the msi file using Orca. In the InstallExecuteSequence table, I
> see that the InstallExecute operation has a sequence number 6500 and the
> RemoveExistingProducts a sequence number 6550. Can I swap the two and expect
> it to work the way I want to (i.e. remove old version first and then install
> new version) ??
I assume RemoveExistingProducts would then be preceded by
PublishProduct and followed by InstallExecute. That would
violate the sequence restrictions for RemoveExistingProducts:
http://msdn.microsoft.com/en-us/library/aa371197(VS.85).aspx
If I understand correctly, you want to remove the old version
before starting the service, but not let the user's configuration
files be deleted. Phil Wilson suggested starting the service
with a commit custom action, and that should indeed work.
Other options might include:
- If the user configuration files are in a separate feature in
the old version (seems unlikely), then you could set the
Upgrade table of the new version so that it uninstalls all
other features of the old version but leaves that one
installed.
- Define custom actions that copy or move the data to a safe
place before the old version is removed, then restore it.
This approach seems very error-prone.
- Create a separate MSI package that contains just the
configuration files, with the correct component codes. Then
make a bootstrapper install this configuration-file package,
uninstall the old version, install the new version, and
optionally uninstall the configuration-file package. This
should stop Windows Installer from removing the configuration
files when uninstalling the old version.
- Use the RemoveFile table to directly remove the plugins of the
old version before starting the service, even though the old
version has not yet been uninstalled at that time and Windows
Installer expects the files to still be there. I suppose you
cannot do this if you use self-registration for the plugins.
Overall, the commit custom action seems the easiest and safest
solution.
"Kalle Olavi Niemitalo" wrote:
> .
>
"vijaygos" <vija...@discussions.microsoft.com> wrote in message
news:5F339C1D-F669-4AAD...@microsoft.com...