0

我创建了一个安装 Windows 服务的安装程序。我在 VS 2010 中使用了 Visual Studio 默认安装程序。

该服务将访问和写入安装文件夹中存在的数据库文件 (SQLite)。

在服务停止或运行时的卸载过程中,服务正在卸载而没有任何错误。

但是如果安装程序从版本 1 迁移到 2,并且之前版本的服务正在运行,则会显示“该文件正在被某些应用程序访问。再试一次”错误,因为之前的安装服务访问了 DB 文件。

所以我需要在安装新版本之前停止以前的版本服务。我有一个用于管理安装和卸载的自定义操作脚本。在BeforeInstall方法中,我编写了代码来停止使用ServiceController. 这可以停止服务。

ServiceController service = new ServiceController("SERVICE_NAME");

if (!(service.Status.Equals(ServiceControllerStatus.Stopped)))

    {
        service.Stop();
        service.WaitForStatus   (System.ServiceProcess.ServiceControllerStatus.Stopped);

    }

但即使在BeforeInstall方法之前安装程序正在复制新版本文件替换我以前的版本文件。

我总是有相同的安装文件夹。因此,如果我在 BeforeInstall 自定义操作中编写代码来停止服务,它仍然会抛出错误,因为以前版本服务正在访问的数据库文件试图被新版本删除。所以我得到“文件正在被某些人访问申请。再试一次”。

因此,即使在安装程序将文件复制到安装文件夹之前,我也需要一些钩子。这样我就可以在安装程序尝试更新 Db 文件之前停止服务。

任何想法将不胜感激。

4

1 回答 1

2

Windows Installer 没有“安装前”的概念。这是一个 Visual Studio 安装和部署项目抽象。这种项目类型未能公开许多底层 Windows Installer 功能,这就是微软在 VS2012 中将其淘汰的原因。

另一个未公开的概念是 ServiceInstall 和 ServiceControl 表。这就是您被迫编写自定义操作的原因。以这种方式托管的自定义操作(超出您的控制范围)以使用 CLR 版本标记 MSIEXEC 进程,并在出现问题时抛出模式 1001 异常(即使在静默安装期间)。

但是有一个解决方案。切换到更好的工具,例如免费和开源的 Windows Installer XML (WiX) 和 Industrial Strength Windows Installer XML (IsWiX)。使用这些工具,您可以创建 Windows 服务,为其创建安装程序并在 10 分钟内在 VM 上测试安装/卸载。观看我的无声演示:

使用 IsWiX 构建和部署 Windows 服务

于 2013-10-24T11:36:39.320 回答