【问题标题】:Nsis service removingNsis 服务移除
【发布时间】:2017-06-06 05:46:54
【问题描述】:

您好,我的 NSIS 卸载程序有问题。

我安装了软件并创建了一项服务。服务名称由用户命名(例如troll

我有服务troll 它正在运行,一切正常。

如果我想卸载软件,我必须删除此服务;我用插件simpleSCnsSCM 尝试了几种方法,没有任何帮助。

如果我为前任写信:

  • nsSCM::Remove "troll" 服务被移除
  • 但是当我写nsSCM::Remove "$0" ->什么都没有发生

我的错误在哪里?从堆栈中获取服务名称?我不知道服务的名称,因为它是自定义的,任何帮助都会有所帮助:D

【问题讨论】:

  • 如何获取已安装的服务名称?显示代码,问题可能在另一边。
  • 我在 tomcat 服务上测试它,我以这种方式安装服务:`nsExec::ExecToLog '"$INSTDIR\TamasAppServer\bin\tomcat7.exe" //IS//tomcat7` + 其他信息描述、日志路径、JVM ...等
  • 安装后保存名字吗?你如何回读这个名字?
  • by pop$0 当我做DetailPrint "$0" 它显示服务名称所以我觉得没关系
  • 是的,我尝试了 //DS 的卸载服务

标签: tomcat service nsis


【解决方案1】:

安装程序中的变量内容不会在卸载程序中自动恢复。您必须在注册表中写入服务名称或在安装程序中写入 .INI 文件,然后在卸载程序中读取此值。

【讨论】:

    【解决方案2】:

    我没有任何声誉,否则这会出现在评论中。无论如何,您说服务的名称是“由用户命名

    您是说最终用户指定服务名称还是只是最终用户的用户名?

    如果是后者,你可以在没有任何插件的情况下使用它,不包括 ExecDos:

    Var User
    
    !define SVC `$User`
    !define SC  `$SYSDIR\sc.exe`
    
    System::Call "advapi32::GetUserName(t.r0,*i${NSIS_MAX_STRLEN})i" 
    StrCpy $User $0
    ClearErrors
    ExecDos::Exec /TOSTACK `"${SC}" stop "${SVC}"`
    Sleep 50
    ExecDos::Exec /TOSTACK `"${SC}" delete "${SVC}"`
    

    如果这是第一个选项,那么只要用户指定服务的名称,您就需要在安装程序中执行类似的操作。希望这不是太复杂。

    ;= VARIABLES 
    ;= ################
    Var Bit
    Var UserService
    
    ;= DEFINES
    ;= ################
    !define SVC         `$UserService`
    !define SCKEY       SYSTEM\CurrentControlSet\services\${SVC}
    !define HKLM        HKLM\${SCKEY}
    !define SC          `$SYSDIR\sc.exe`
    !define GETCURRPROC `kernel32::GetCurrentProcess()i.s`
    !define WOW         `kernel32::IsWow64Process(is,*i.r0)`
    
    ;= MACROS
    ;= ################
    ;=#
    ;= Service::Example
    ; ${Service::CMD} "ServiceName" /DISABLEFSR $0 $1
    ;       ::CMD       = Either QueryConfig, Stop, or Remove. 
    ;       ServiceName = The service name to be handled
    ;       /DISABLEFSR = Disables file-system redirection if running on x64. Use "" to skip.
    ;       $0          = Return after call
    ;       $1          =  ''     ''    ''
    !define Service::QueryConfig `!insertmacro _Service::QueryConfig`
    !macro _Service::QueryConfig _SVC _FSR _ERR1 _ERR2
        ReadEnvStr $R0 COMSPEC
        StrCmpS $Bit 64 0 +4
        StrCmp "${_FSR}" /DISABLEFSR 0 +3
        ExecDos::Exec /TOSTACK /DISABLEFSR `"$R0" /c "${SC} qc "${_SVC}" | FIND "BINARY_PATH_NAME""`
        Goto +2
        ExecDos::Exec /TOSTACK `"$R0" /c "${SC} qc "${_SVC}" | FIND "BINARY_PATH_NAME""`
        Pop ${_ERR1}
        Pop ${_ERR2}
        StrCmpS ${_ERR1} 0 0 +4
        StrCpy $R1 ${_ERR2} "" 29
        WriteINIStr "$EXEDIR\InstallData.ini" "Service" Path "$R1"
        ReadRegStr $R1 HKLM `${SVCKEY}` ImagePath
        WriteINIStr "$EXEDIR\InstallData.ini" "Service" Path "$R1"
        WriteINIStr "$EXEDIR\InstallData.ini" "Service" Name "${_SVC}"
    !macroend
    !define Service::Stop `!insertmacro _Service::Stop`
    !macro _Service::Stop _SVC _FSR _ERR1 _ERR2
        StrCmpS $Bit 64 0 +4
        StrCmp "${_FSR}" /DISABLEFSR 0 +3
        ExecDos::Exec /TOSTACK /DISABLEFSR `"${SC}" stop "${_SVC}"`
        Goto +2
        ExecDos::Exec /TOSTACK `"${SC}" stop "${_SVC}"`
        Pop ${_ERR1}
        Pop ${_ERR2}
    !macroend
    !define Service::Remove `!insertmacro _Service::Remove`
    !macro _Service::Remove _SVC _FSR _ERR1 _ERR2
        StrCmpS $Bit 64 0 +4
        StrCmp "${_FSR}" /DISABLEFSR 0 +3
        ExecDos::Exec /TOSTACK /DISABLEFSR `"${SC}" delete "${_SVC}"`
        Goto +2
        ExecDos::Exec /TOSTACK `"${SC}" delete "${_SVC}"`
        Pop ${_ERR1}
        Pop ${_ERR2}
    !macroend
    
    Function ".onInit" 
        System::Call `${GETCURRPROC}`
        System::Call `${WOW}`
        StrCmpS $0 0 +3
        StrCpy $Bit 64
        Goto +2
        StrCpy $Bit 32
    FunctionEnd 
    
    ;=#
    ;= I don't know the code you're using but let's assume 
    ;= after the end-user specifies the service's name you
    ;= copy the name to the variable $UserService. This is
    ;= somewhere in the install process.
    
    
    StrCpy $UserService $0
    ;#=#
    ;# This will write to an INI file | $EXEDIR\InstallData.ini
    ;#      [Service]
    ;#      Path=X:\Path\to\service\exe
    ;#      Name=ServiceName 
    ;#=#
    ${Service::QueryConfig} ${SVC} /DISABLEFSR $0 $1
    
    ;=#
    ;= Then in your uninstaller you could simply implement
    ;= this into your code for easy removal. I usually use
    ;= this method in my projects and it works pretty good
    ;= without the need for any extra plugins. 
    ReadINIStr $0 "$EXEDIR\InstallData.ini" "Service" Name
    ${Service::Stop} "$0" /DISABLEFSR $0 $1
    Sleep 50
    ${Service::Remove} "$0" /DISABLEFSR $0 $1
    

    /DISABLEFSR 参数只能在 x64 机器上使用。但是,如果你搞砸了,宏中有一个故障保护装置可以为你躲避这个子弹。男孩,那是很多,是吧?幸运的是,这绝不会帮助你。哈哈。希望这对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-14
      • 1970-01-01
      • 1970-01-01
      • 2012-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多