Installation 使用Inno安装程序升级Windows服务

Installation 使用Inno安装程序升级Windows服务,installation,inno-setup,Installation,Inno Setup,我已经使用Inno安装程序创建了一个基本的Windows服务安装。安装和卸载都能正常工作 但是,我在升级过程中遇到了问题 为了升级服务可执行文件,必须停止服务,并且只有在服务完全停止后,更新的可执行文件才能放在目标文件夹中 在启动文件部署步骤之前,如何执行服务停止命令并等待服务完全停止?这有两个部分: 使用Inno Setup创建的安装程序如何启动和停止服务,如何创建和删除服务,如何更改启动模式 通过使用本文中提供的帮助器函数,可以实现这一目的。它是为Inno Setup的Ansi版本编写的,因

我已经使用Inno安装程序创建了一个基本的Windows服务安装。安装和卸载都能正常工作

但是,我在升级过程中遇到了问题

为了升级服务可执行文件,必须停止服务,并且只有在服务完全停止后,更新的可执行文件才能放在目标文件夹中


在启动文件部署步骤之前,如何执行服务停止命令并等待服务完全停止?

这有两个部分:

  • 使用Inno Setup创建的安装程序如何启动和停止服务,如何创建和删除服务,如何更改启动模式

    通过使用本文中提供的帮助器函数,可以实现这一目的。它是为Inno Setup的Ansi版本编写的,因此需要对API函数导入和
    PChar
    参数类型进行更改,但这应该可以帮助您开始

  • 在复制新文件版本之前,如何停止现有服务

    基本上有两种方法。您可以使用Pascal脚本来执行上面链接的函数来停止服务,您只需要决定是在其中一个事件函数中执行,还是在自定义函数中执行,该自定义函数将通过服务可执行文件项的
    Check
    参数调用。我肯定会在前者中这样做,因此您可以检查服务是否已成功停止,并禁止在失败时实际启动安装

    您应该查看
    CurStepChanged()
    NextButtonClick()
    事件函数,这取决于您是否可能需要阻止下一步。Inno设置示例演示了这两个函数的使用


  • 下面的代码来自以下页面:

    然而,我必须应用一个小的修正,使其工作

    请注意,我最初在2010年发布了这个答案。代码在 上面的页面是在2011年更新的,所以可能值得一看

    我在安装程序中使用此代码作为
    #include
    。它是在Inno SetupANSI中编译的
    通过在所有
    外部
    声明中将
    A@
    替换为
    W@
    ,它可能适用于Inno设置的Unicode版本(感谢JeroenviertLuimers指出这一点)

    还请注意,
    StartService
    StopService
    仅发送启动/停止信号,但不要等待服务处于停止状态运行。您可以使用using
    IsServiceRunning
    和Pascal脚本
    Sleep()
    函数来构造等待服务运行的代码。或者只需
    Sleep()
    预定义的秒数

    该代码实现以下功能:

    函数IsServiceInstalled(ServiceName:string):布尔值;
    函数IsServiceRunning(ServiceName:string):布尔值;
    函数InstallService(文件名、ServiceName、DisplayName、说明:字符串;ServiceType、StartType:基数):布尔值;
    函数RemoveService(ServiceName:string):布尔值;
    函数StartService(ServiceName:string):布尔值;
    函数StopService(ServiceName:string):布尔值;
    函数SetupService(服务、端口、注释:字符串):布尔值;
    
    实际代码:

    类型
    服务状态=记录
    dwServiceType:基数;
    当前状态:红衣主教;
    接受:红衣主教;
    dwWin32ExitCode:cardinal;
    dwServiceSpecificExitCode:基数;
    检查点:红衣主教;
    dwWaitHint:红衣主教;
    结束;
    句柄=基数;
    常数
    服务查询配置=$1;
    服务更改配置=$2;
    服务查询状态=$4;
    服务开始价=10美元;
    服务站=20美元;
    服务所有访问权=$f01ff;
    SC_MANAGER_ALL_ACCESS=$f003f;
    服务(WIN32)(OWN)(进程)=$10 ;;
    服务\ WIN32 \共享\进程=$20;
    服务(WIN32=$30 ;;
    服务交互过程=100美元;
    服务启动启动=0美元;
    服务系统启动=1美元;
    服务自动启动=2美元;
    服务需求启动=3美元;
    服务费=4美元;
    服务费=10000美元;
    服务控制站=1美元;
    服务控制暂停=2美元;
    服务控制继续=3美元;
    服务控制询问=4美元;
    已停止的服务=1美元;
    服务(启动)(挂起)=$2 ;;
    服务停止等待=3美元;
    服务费=4美元;
    服务_CONTINUE _PENDING=$5;
    服务暂停暂停暂停=6美元;
    服务费=7美元;
    {基于nt的服务实用程序}
    函数OpenSCManager(lpMachineName,lpDatabaseName:string;dwDesiredAccess:cardinal):句柄;
    外部的OpenSCManagerA@advapi32.dllstdcall';
    函数OpenService(hSCManager:HANDLE;lpServiceName:string;dwDesiredAccess:cardinal):句柄;
    外部的OpenServiceA@advapi32.dllstdcall';
    函数CloseServiceHandle(hSCObject:HANDLE):布尔值;
    外部的CloseServiceHandle@advapi32.dllstdcall';
    函数CreateService(hSCManager:HANDLE;lpServiceName,lpDisplayName:string;dwDesiredAccess,dwServiceType,dwStartType,dwErrorControl:cardinal;lpBinaryPathName,lpLoadOrderGroup:string;lpdwTagId:cardinal;lpDependencies,lpServiceStartName,lpPassword:string):cardinal;
    外部的CreateServiceA@advapi32.dllstdcall';
    函数DeleteService(hService:HANDLE):布尔值;
    外部的DeleteService@advapi32.dllstdcall';
    函数StartNTService(hsservice:HANDLE;dwNumServiceArgs:cardinal;lpServiceArgVectors:cardinal):布尔;
    外部的StartServiceA@advapi32.dllstdcall';
    功能控制服务(hs服务:句柄;d
    
    [Run]
    Filename: "{app}\Scripts\installwindowsService.bat"; Parameters: "{app}"; Flags: runhidden
    
    net stop MyService
    
    %SYSTEMROOT%\Microsoft.NET\Framework\v4.0.30319\installutil.exe /u MyService.exe 
    
    %SYSTEMROOT%\Microsoft.NET\Framework\v4.0.30319\installutil.exe  MyService.exe /unattended
    
    net start MyService