使用Windows Installer启动依赖于并行程序集的服务

时间:2022-05-02 14:10:22

We are in the process of updating the construction of our product's .msi package for Windows Server 2008. The main component of our install is an application that is run as a Windows service. There is also a configuration application that gets run during install to set up registry entries for use by the service.

我们正在更新Windows Server 2008产品的.msi包的构建。我们安装的主要组件是作为Windows服务运行的应用程序。还有一个配置应用程序在安装期间运行,以设置供服务使用的注册表项。

The service and the configuration application rely on the Microsoft C/C++ runtime and MFC, which are included in the .msi as merge modules. The assemblies for the C/C++ runtime and MFC are committed during the InstallFinalize, which seems to preclude the starting of the service using the mechanisms provided by Windows Installer (is this correct?) Certainly, we see side-by-side errors with at least the configuration application if it is run before InstallFinalize.

服务和配置应用程序依赖于Microsoft C / C ++运行时和MFC,它们作为合并模块包含在.msi中。 C / C ++运行时和MFC的程序集在InstallFinalize期间提交,这似乎阻止了使用Windows Installer提供的机制启动服务(这是正确的吗?)当然,我们看到并行错误。至少是配置应用程序,如果它在InstallFinalize之前运行。

The approach we have taken is to run the configuration application as a "commit" custom action after InstallFinalize, and have this application start the service. This requires that the application is executed with elevated privileges (for which we use a manifest containing a trustInfo section.) This further requires that the .msi is configured to run this application without Impersonation (which otherwise confounds the privilege elevation.)

我们采取的方法是在InstallFinalize之后将配置应用程序作为“提交”自定义操作运行,并让此应用程序启动该服务。这要求应用程序以提升的权限执行(我们使用包含trustInfo部分的清单。)这进一步要求.msi配置为在没有模拟的情况下运行此应用程序(否则会使权限提升混乱。)

Is this an acceptable approach? How future-proof is this likely to be? Are there any gotchas to be aware of?

这是一种可接受的方法吗?这可能是未来的证据吗?有什么问题需要注意吗?

It seems that this is a problem that has been encountered by others:

看来这是其他人遇到的问题:

http://www.mail-archive.com/wix-users@lists.sourceforge.net/msg12666.html

Is there an officially (or unofficially) accepted way to deal with such problems?

是否有正式(或非正式)接受的方式来处理这些问题?

As an addendum to this, is there any way of ensuring that an application run as a custom action during the install process gets focus when it starts up? Applications started in this manner always seem to pop up behind the installer and the installer keeps focus, which is not a particularly user-friendly effect.

作为对此的补充,有没有办法确保在安装过程中作为自定义操作运行的应用程序在启动时获得焦点?以这种方式启动的应用程序似乎总是弹出安装程序,安装程序保持焦点,这不是一个特别用户友好的效果。

Many Thanks,

Bruce.

2 个解决方案

#1


Here's a solution I've used for this kind of problem when re-packaging software with Windows Installer: a "bootstrap" launcher. In short, instead of using the merge modules for the runtime (which will all commit at the same time as all your other installed files), you can do one of the following:

这是我用Windows Installer重新打包软件时用于此类问题的解决方案:“bootstrap”启动器。简而言之,您可以执行以下操作之一,而不是使用运行时的合并模块(它们将与所有其他已安装的文件同时提交)。

  1. Provide the redistributable MSIs for the runtime/MFCs, and have them launched first by your bootstrapper setup.exe. Your program's MSI must of course test that the version you need is installed and maybe even test to ensure that you're running it from your setup.exe. (This method was popularized by InstallShield, as they like to do the end-run around Windows Installer.)

    为运行时/ MFC提供可再发行的MSI,并首先由引导程序setup.exe启动它们。您的程序的MSI当然必须测试您所需的版本是否已安装,甚至可能进行测试以确保您从setup.exe运行它。 (这种方法由InstallShield推广,因为他们喜欢围绕Windows Installer进行最终运行。)

  2. Better yet, you can package your MSI as a parent package that installs two (or more) embedded MSIs: first, install the required runtimes, then install your software in a child MSI. Your parent package will confirm that the runtimes' MSI installed successfully before continuing on to install your MSI (which has the freedom to start the services since the prerequisites are already there).

    更好的是,您可以将MSI打包为安装两个(或更多)嵌入式MSI的父包:首先,安装所需的运行时,然后在子MSI中安装您的软件。在继续安装MSI之前,您的父包将确认运行时'MSI已成功安装(由于先决条件已经存在,因此可以*启动服务)。

There are other tricksy methods, like your early-commit custom action, but they are not as dependable as the time-tested ones I just mentioned.

还有其他棘手的方法,比如早期提交的自定义操作,但它们不像我刚才提到的经过时间考验的方法那样可靠。

Hope that makes sense! I used to live and breathe MSI, but not so much anymore these days...

希望有道理!我曾经生活和呼吸MSI,但现在已经不再那么多......

#2


  1. You can compiler your static use of MFC&C-Runtime so this way you won't be dpeneded upon it.
  2. 您可以编译静态使用MFC和C-Runtime,这样您就不会对它进行任何操作。

  3. You can add UI to the setup this will act as the configuration program, so you won't need to run the configuration program during setup (which is btw not a good idea)
  4. 您可以将UI添加到设置中,这将作为配置程序,因此您无需在安装过程中运行配置程序(这不是一个好主意)

  5. You can install the service in disable mode, and run the configuration when the setup has terminated. The configuration will be responsible for activating the service.
  6. 您可以在禁用模式下安装该服务,并在安装程序终止时运行配置。配置将负责激活服务。

#1


Here's a solution I've used for this kind of problem when re-packaging software with Windows Installer: a "bootstrap" launcher. In short, instead of using the merge modules for the runtime (which will all commit at the same time as all your other installed files), you can do one of the following:

这是我用Windows Installer重新打包软件时用于此类问题的解决方案:“bootstrap”启动器。简而言之,您可以执行以下操作之一,而不是使用运行时的合并模块(它们将与所有其他已安装的文件同时提交)。

  1. Provide the redistributable MSIs for the runtime/MFCs, and have them launched first by your bootstrapper setup.exe. Your program's MSI must of course test that the version you need is installed and maybe even test to ensure that you're running it from your setup.exe. (This method was popularized by InstallShield, as they like to do the end-run around Windows Installer.)

    为运行时/ MFC提供可再发行的MSI,并首先由引导程序setup.exe启动它们。您的程序的MSI当然必须测试您所需的版本是否已安装,甚至可能进行测试以确保您从setup.exe运行它。 (这种方法由InstallShield推广,因为他们喜欢围绕Windows Installer进行最终运行。)

  2. Better yet, you can package your MSI as a parent package that installs two (or more) embedded MSIs: first, install the required runtimes, then install your software in a child MSI. Your parent package will confirm that the runtimes' MSI installed successfully before continuing on to install your MSI (which has the freedom to start the services since the prerequisites are already there).

    更好的是,您可以将MSI打包为安装两个(或更多)嵌入式MSI的父包:首先,安装所需的运行时,然后在子MSI中安装您的软件。在继续安装MSI之前,您的父包将确认运行时'MSI已成功安装(由于先决条件已经存在,因此可以*启动服务)。

There are other tricksy methods, like your early-commit custom action, but they are not as dependable as the time-tested ones I just mentioned.

还有其他棘手的方法,比如早期提交的自定义操作,但它们不像我刚才提到的经过时间考验的方法那样可靠。

Hope that makes sense! I used to live and breathe MSI, but not so much anymore these days...

希望有道理!我曾经生活和呼吸MSI,但现在已经不再那么多......

#2


  1. You can compiler your static use of MFC&C-Runtime so this way you won't be dpeneded upon it.
  2. 您可以编译静态使用MFC和C-Runtime,这样您就不会对它进行任何操作。

  3. You can add UI to the setup this will act as the configuration program, so you won't need to run the configuration program during setup (which is btw not a good idea)
  4. 您可以将UI添加到设置中,这将作为配置程序,因此您无需在安装过程中运行配置程序(这不是一个好主意)

  5. You can install the service in disable mode, and run the configuration when the setup has terminated. The configuration will be responsible for activating the service.
  6. 您可以在禁用模式下安装该服务,并在安装程序终止时运行配置。配置将负责激活服务。