从Linux或Mac签署NSIS卸载程序

从Linux或Mac签署NSIS卸载程序,nsis,Nsis,我正在将我们的NSI安装程序移植到Linux和Mac而不是Windows,以便更好地与我们的Maven构建系统集成 我们需要签署我们的安装程序和卸载程序。这是按照上的建议完成的,但我刚刚意识到它试图运行tempinstaller来强制它生成卸载程序.exe,然后可以对其进行签名 显然,这个技巧在*Nix系统上效果不太好,并且使这部分过程不可移植 有谁有更好的解决方案吗。我不是NSIS方面的专家,我想知道是否有一种聪明的方法来获取uninstall.exe以便对其进行签名?我认为没有真正的解决方案

我正在将我们的NSI安装程序移植到Linux和Mac而不是Windows,以便更好地与我们的Maven构建系统集成

我们需要签署我们的安装程序和卸载程序。这是按照上的建议完成的,但我刚刚意识到它试图运行tempinstaller来强制它生成卸载程序.exe,然后可以对其进行签名

显然,这个技巧在*Nix系统上效果不太好,并且使这部分过程不可移植


有谁有更好的解决方案吗。我不是NSIS方面的专家,我想知道是否有一种聪明的方法来获取uninstall.exe以便对其进行签名?

我认为没有真正的解决方案

安装程序和卸载程序使用相同的exe代码,仅在启动时检查
firstheader
中的标志(
FH\u FLAGS\u UNINSTALL
),以查看它是否为卸载程序。不过,仅仅翻转这个位是不够的,程序将无法通过CRC检查,即使您绕过卸载程序数据被压缩,您也必须将其解压缩到文件中的正确位置。要真正做到这一点,您必须编写一个自定义工具。如果搜索
EW\u WRITEUNINSTALLER
,您可以在exec.c中的NSIS源代码中看到此操作

我们需要签署我们的安装程序和卸载程序。这是按照上的建议完成的,但我刚刚意识到它试图运行tempinstaller来强制它生成卸载程序.exe,然后可以对其进行签名。[…]这个技巧在*Nix系统上效果不太好,使这部分过程不可移植

如果您利用存根安装程序进行卸载操作(无有效负载),这似乎是可能的

它将从
$TEMP
文件夹中生成一个
uninstall.exe
进程,然后该进程可以删除
$INSTDIR

此脚本将创建一个存根(un)安装程序,然后可以对其进行身份验证码签名。它将在Windows、MacOS和Linux上编译

注意事项:
  • 您必须手动将其捆绑到安装程序中(琐碎)
  • 您必须管理自己的卸载注册表项(琐碎)
  • 外观可能与NSIS的默认卸载程序不匹配
  • 您将看到安装程序打开两次(第一次从
    $INSTDIR
    ,第二次从
    $TEMP
    )。这是一个允许
    uninstall.exe
    删除自身的子进程,与此类似
  • 您将需要一个专用于卸载操作的辅助
    .nsi
    脚本,如果您在安装/卸载部分之间有很多共享逻辑,那么这个脚本会很麻烦。
    • 更糟糕的是,您必须避免
      “卸载”
      部分标题
      ,因为在生成字节码时,您将遇到与OP相同的问题
  • 当从
    $TEMP
    显式运行时,某些相关文件逻辑将不正确。该示例分别以
    $DELETE\u DIR
    $DELETE\u EXE
    的形式将这些文件传回
守则:
编写卸载程序与将卸载程序行为(但复制到“安装”部分)复制到全新的安装程序中并将其捆绑在一起有什么区别?回答我自己的问题……最棘手的部分似乎是卸载程序的自删除行为(复制到临时,然后在重新启动时删除自身)。插件有一个处理此问题的技巧,但底部有一个警告,说明卡巴斯基已将此技术标记为威胁,因为它使用内存注入/资源管理器挂起技术。作为替代方案,发布了NSIS
!ifdef internal
自我执行技术,尽管reinv可能可行给俗话所说的轮子上一个圆。
!include MUI2.nsh
!include x64.nsh
!include LogicLib.nsh
!include FileFunc.nsh
!include WinMessages.nsh

!define MUI_PRODUCT "My App"
!define MUI_VERSION "1.0.0"

; Masquerade the title
!define MUI_PAGE_HEADER_TEXT "Uninstall My App"
!define MUI_PAGE_HEADER_SUBTEXT "Remove My App from your computer"
!define MUI_INSTFILESPAGE_FINISHHEADER_TEXT "Uninstallation Complete"
!define MUI_INSTFILESPAGE_FINISHHEADER_SUBTEXT "Uninstall was completed successfully."

!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"
!insertmacro GetParameters

RequestExecutionLevel admin
CRCCheck On

OutFile "uninstall.exe"
Name "Uninstall"

Var /GLOBAL RESPAWN
Var /GLOBAL DELETE_DIR
Var /GLOBAL DELETE_EXE

Section
  ; Masquerade as uninstall
  SendMessage $HWNDPARENT ${WM_SETTEXT} 0 "STR:Uninstall"

  ${GetParameters} $0
  ${GetOptions} "$0" "/RESPAWN=" $RESPAWN
  ${GetOptions} "$0" "/DELETE_DIR=" $DELETE_DIR
  ${GetOptions} "$0" "/DELETE_EXE=" $DELETE_EXE

  ${If} $RESPAWN != ""
    ; We're running from $TEMP; Perform the uninstall
    !define yay "We're running from $EXEPATH, yay, we can remove the install directory!$\n$\n"
    !define myvars "$\tRESPAWN$\t$RESPAWN$\n$\tDELETE_EXE$\t$DELETE_EXE$\n$\tDELETE_DIR$\t$DELETE_DIR"
    MessageBox MB_OK "${yay}${myvars}"
    ; Your uninstall code goes here
    ; RMDir /r $DELETE_DIR\*.*
    ; Delete "$DESKTOP\${MUI_PRODUCT}.lnk"
    ; Delete "$SMPROGRAMS\${MUI_PRODUCT}\*.*"
    ; RmDir  "$SMPROGRAMS\${MUI_PRODUCT}"
    ; Delete Uninstaller And Unistall Registry Entries
    ; DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\${MUI_PRODUCT}"
    ; DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\${MUI_PRODUCT}"  

    ; Remove the old version of ourself
    ClearErrors
    Delete $DELETE_EXE
    IfErrors 0 +3
    MessageBox MB_OK "File could NOT be deleted: $DELETE_EXE"
    Goto +2
    MessageBox MB_OK "File was successfully deleted: $DELETE_EXE"

    ; Remove ourself from $TEMP after reboot
    Delete /REBOOTOK $EXEPATH

    ; ${If} ${RunningX64}
    ;   ${EnableX64FSRedirection}
    ; ${EndIf}
    SetDetailsPrint textonly
    DetailPrint "Completed"
  ${Else}
    ; We're NOT running from $TEMP, copy to temp and respawn ourself
    GetTempFileName $0
    CopyFiles "$EXEPATH" "$0"
    Exec '"$0" /RESPAWN=1 /DELETE_DIR="$EXEDIR" /DELETE_EXE="$EXEPATH"'
    Quit
  ${EndIf}
SectionEnd

Function .onInit
  ; ${If} ${RunningX64}
  ;   SetRegView 64
  ;   ${DisableX64FSRedirection}
  ; ${EndIf}
FunctionEnd