Scoop icon indicating copy to clipboard operation
Scoop copied to clipboard

feat(install): Add unpacker for 'wix', 'nsis' and 'inno' installer

Open niheaven opened this issue 6 years ago • 14 comments

  • Add a new property installer.type (nsis|wix|inno)
    • nsis: Expand-Installer accepts $Architecture (64bit|32bit) and unpack Electron's NSIS installer ($PLUGINSDIR/app-32|64.7z)
    • wix: Expand-WixInstaller use Expand-DarkArchive first and then Expand-MsiArchive all msi under AttachedContainer except those excluded by installer.exclude
    • inno: Move innosetup here for consistency, i.e. innosetup:true = installer.type:inno (autoupdate will remove innosetup:true and add installer.type:inno automatically), installer.include are MUST HAVE components while installer.exclude are MUST HAVE NOT components
      • All source dir are extracted excepts {tmp} and those excluded by installer.exclude, see freedownloadmanager example ({code_CefInstallDir} is auto extracted)
  • You can also use installer:inno as shortcut of installer.type:inno (thank @linsui)
  • See more examples: https://github.com/ScoopInstaller/Main/pull/121, https://github.com/lukesampson/scoop-extras/pull/2264

Closes #3700

Some Examples:

`python` manifest
"installer": {
    "type": "wix",
    "exclude": [
        "launcher.msi",
        "path.msi",
        "pip.msi"
    ],
    "script": [
        "&(\"$dir\\python.exe\") -E -s -m ensurepip -U --default-pip | Out-Null",
        "if ($global) { $pathext = (env 'PATHEXT' $true) -replace ';.PYW?', ''; env 'PATHEXT' $true \"$pathext;.PY;.PYW\" }"
    ]
},
`mro` manifest
"installer": {
    "type": "wix",
    "script": [
        "movedir \"$dir\\Microsoft\\MRO-$version.0\" \"$dir\" | Out-Null",
        "Expand-7zipArchive \"$dir\\Setup\\*.cab\"",
        "Remove-Item \"$dir\\bin\\x64\\Rblas.dll\", \"$dir\\bin\\x64\\Rlapack.dll\" -Force",
        "movedir \"$dir\\Setup\\bin\\x64\" \"$dir\\bin\\x64\" | Out-Null",
        "movedir \"$dir\\Setup\\library\" \"$dir\\library\" | Out-Null",
        "Remove-Item \"$dir\\Setup\", \"$dir\\Microsoft\" -Force -Recurse"
    ]
},
`simplenote` manifest
"installer": {
    "type": "nsis"
},
`gimp` manifest
"installer": {
    "type": "inno",
    "include": [
        "gimp32on64",
        "gs",
        "py"
    ],
    "exclude": [
        "gimp32",
        "deps32",
        "debug",
        "{sys}"
    ],
    "script": [
        "$defpath = \"`nPATH=`${gimp_installation_dir}\\bin\"",
        "if ($architecture -eq '64bit') {",
        "   $defpath += \"`${gimp_installation_dir}\\32\\bin\"",
        "}",
        "$defenv = Get-Content \"$dir\\lib\\gimp\\2.0\\environ\\default.env\" -Raw",
        "$defenv += $defpath",
        "$defenv += 'PYTHONPATH=${gimp_installation_dir}\\lib\\gimp\\2.0\\python;${gimp_plug_in_dir}\\plug-ins\\python-console'",
        "$defenv | Set-Content \"$dir\\lib\\gimp\\2.0\\environ\\default.env\"",
        "$pyenv = Get-Content \"$dir\\lib\\gimp\\2.0\\environ\\pygimp.env\" -Raw",
        "$pyenv += '__COMPAT_LAYER=HIGHDPIAWARE'",
        "$pyenv | Set-Content \"$dir\\lib\\gimp\\2.0\\environ\\pygimp.env\"",
        "$pyint = Get-Content \"$dir\\lib\\gimp\\2.0\\interpreters\\pygimp.interp\" -Raw",
        "$pyint = ($pyint -Replace '/mingw32', \"$dir\\bin\") -Replace 'py::python2', 'py::python'",
        "$pyint | Set-Content \"$dir\\lib\\gimp\\2.0\\interpreters\\pygimp.interp\""
    ]
},
`scilab` manifest
"installer": {
    "type": "inno",
    "include": [
        "CPU_OPTIMIZATION\\MKL",
        "FFTW\\MKL_LIBRARY",
        "JVM_MODULE\\graphics\\xcos"
    ],
    "script": [
        "New-Item -Path \"$dir\\.atoms\" -ItemType Directory | Out-Null",
        "$modules = Get-Content \"$dir\\etc\\modules.xml\"",
        "$modules | Where-Object { $_ -notlike '*parallel*' } | Set-Content \"$dir\\etc\\modules.xml\" -Encoding ASCII"
    ]
},
`freedownloadmanager` manifest
"installer": {
    "type": "inno"
},

niheaven avatar Jun 10 '19 15:06 niheaven

~~KNOWN ISSUE: Error while aria2 enabled.~~ ~~Will fix soon.~~

Fixed.

niheaven avatar Jun 19 '19 04:06 niheaven

~~I'll work out general INNO unpacker that could treat ,1, ,2 files automatically, maybe by parsing install_script.iss. And just likes wix's exclude section, a default or include section will be added. This may behave like original installation.~~

~~Motivation: Complex inno-type installer.script, e.g., GIMP and SciLab(not submitted).~~

Inno type is done.

niheaven avatar Jul 07 '19 16:07 niheaven

How about something like "installer": "inno" ?

linsui avatar Sep 01 '19 15:09 linsui

opentoonz.json
{
    "version": "1.3.0",
    "homepage": "https://opentoonz.github.io/",
    "description": "A full-featured 2D animation creation software.",
    "license": {
        "identifier": "BSD-3-Clause,...",
        "url": "https://github.com/opentoonz/opentoonz/blob/master/LICENSE.txt"
    },
    "url": "https://github.com/opentoonz/opentoonz/releases/download/v1.3.0/OpenToonzSetup.exe",
    "hash": "b321c528149f919fac6eee9bb63ace243413311163d74b4760b864255a16d0d9",
    "innosetup": true,
    "checkver": {
        "github": "https://github.com/opentoonz/opentoonz"
    },
    "autoupdate": {
        "url": "https://github.com/opentoonz/opentoonz/releases/download/v$version/OpenToonzSetup.exe"
    }
}

This manifest works well (can decompress the installer successfully but can't be used because of the limitation of the app itself) with develop branch but failed with this branch.

output
WARN  'innosetup' is deprecated, please use 'installer.type:inno' instead.
WARN  If you maintain this manifest, please refer to the manifest reference docs.
Installing 'opentoonz' (1.3.0) [64bit]
Loading OpenToonzSetup.exe from cache
Checking hash of OpenToonzSetup.exe ... ok.
Extracting OpenToonzSetup.exe ... ERROR Exit code was 1!
Failed to extract files from D:\Scoop\apps\opentoonz\1.3.0\OpenToonzSetup.exe.
Log file:
  D:\Scoop\apps\opentoonz\1.3.0\innounp.log

Please try again or create a new issue by using the following link and paste your console output:    
https://github.com/Ash258/GenericBucket/issues/new?title=opentoonz%401.3.0%3a+decompress+error
innounp.log
; Version detected: 5507 (Unicode)
#121 {code_GetGeneralDir}\config\batches,1.xml
Reading slice D:\Scoop\apps\opentoonz\1.3.0\OpenToonzSetup.exe
#122 {code_GetGeneralDir}\config\batches,2.xml
#123 {code_GetGeneralDir}\config\brush,1.txt
#124 {code_GetGeneralDir}\config\brush,2.txt
#125 {code_GetGeneralDir}\config\cleanupreslist,1.txt
#126 {code_GetGeneralDir}\config\cleanupreslist,2.txt
#127 {code_GetGeneralDir}\config\current,1.txt
#128 {code_GetGeneralDir}\config\current,2.txt
#129 {code_GetGeneralDir}\config\export-toonz,1.lua
#130 {code_GetGeneralDir}\config\export-toonz,2.lua
#131 {code_GetGeneralDir}\config\permissions,1.xml
#132 {code_GetGeneralDir}\config\permissions,2.xml
#133 {code_GetGeneralDir}\config\reslist,1.txt
#134 {code_GetGeneralDir}\config\reslist,2.txt
#135 {code_GetGeneralDir}\config\safearea,1.ini
#136 {code_GetGeneralDir}\config\safearea,2.ini
#137 {code_GetGeneralDir}\config\versioncontrol,1.xml
#138 {code_GetGeneralDir}\config\versioncontrol,2.xml
#139 {code_GetGeneralDir}\config\fdg\fld_10_4mm_acme,1.fdg
#140 {code_GetGeneralDir}\config\fdg\fld_10_4mm_acme,2.fdg
#141 {code_GetGeneralDir}\config\fdg\fld_12_4mm_acme,1.fdg
#142 {code_GetGeneralDir}\config\fdg\fld_12_4mm_acme,2.fdg
#143 {code_GetGeneralDir}\config\fdg\fld_12_acme,1.fdg
#144 {code_GetGeneralDir}\config\fdg\fld_12_acme,2.fdg
#145 {code_GetGeneralDir}\config\fdg\fld_12_oxbry,1.fdg
#146 {code_GetGeneralDir}\config\fdg\fld_12_oxbry,2.fdg
#147 {code_GetGeneralDir}\config\fdg\fld_15_4mm_acme,1.fdg
#148 {code_GetGeneralDir}\config\fdg\fld_15_4mm_acme,2.fdg
#149 {code_GetGeneralDir}\config\fdg\fld_16_acme,1.fdg
#150 {code_GetGeneralDir}\config\fdg\fld_16_acme,2.fdg
#151 {code_GetGeneralDir}\config\fdg\fld_16_oxbry,1.fdg
#152 {code_GetGeneralDir}\config\fdg\fld_16_oxbry,2.fdg
#153 {code_GetGeneralDir}\config\fdg\jpn_cel_film,1.fdg
#154 {code_GetGeneralDir}\config\fdg\jpn_cel_film,2.fdg
#155 {code_GetGeneralDir}\config\fdg\jpn_cel_tv,1.fdg
#156 {code_GetGeneralDir}\config\fdg\jpn_cel_tv,2.fdg
#157 {code_GetGeneralDir}\config\loc\Deutsch\colorfx,1.qm
#158 {code_GetGeneralDir}\config\loc\Deutsch\colorfx,2.qm
#159 {code_GetGeneralDir}\config\loc\Deutsch\tnzcore,1.qm
#160 {code_GetGeneralDir}\config\loc\Deutsch\tnzcore,2.qm
#161 {code_GetGeneralDir}\config\loc\Deutsch\tnztools,1.qm
#162 {code_GetGeneralDir}\config\loc\Deutsch\tnztools,2.qm
#163 {code_GetGeneralDir}\config\loc\Deutsch\toonz,1.qm
#164 {code_GetGeneralDir}\config\loc\Deutsch\toonz,2.qm
#165 {code_GetGeneralDir}\config\loc\Deutsch\toonzlib,1.qm
#166 {code_GetGeneralDir}\config\loc\Deutsch\toonzlib,2.qm
#167 {code_GetGeneralDir}\config\loc\Deutsch\toonzqt,1.qm
#168 {code_GetGeneralDir}\config\loc\Deutsch\toonzqt,2.qm
#169 {code_GetGeneralDir}\config\loc\Espa?ol\colorfx,1.qm
#170 {code_GetGeneralDir}\config\loc\Espa?ol\colorfx,2.qm
#171 {code_GetGeneralDir}\config\loc\Espa?ol\image,1.qm
#172 {code_GetGeneralDir}\config\loc\Espa?ol\image,2.qm
#173 {code_GetGeneralDir}\config\loc\Espa?ol\tnzcore,1.qm
#174 {code_GetGeneralDir}\config\loc\Espa?ol\tnzcore,2.qm
#175 {code_GetGeneralDir}\config\loc\Espa?ol\tnztools,1.qm
#176 {code_GetGeneralDir}\config\loc\Espa?ol\tnztools,2.qm
#177 {code_GetGeneralDir}\config\loc\Espa?ol\toonz,1.qm
#178 {code_GetGeneralDir}\config\loc\Espa?ol\toonz,2.qm
#179 {code_GetGeneralDir}\config\loc\Espa?ol\toonzlib,1.qm
#180 {code_GetGeneralDir}\config\loc\Espa?ol\toonzlib,2.qm
#181 {code_GetGeneralDir}\config\loc\Espa?ol\toonzqt,1.qm
#182 {code_GetGeneralDir}\config\loc\Espa?ol\toonzqt,2.qm
#183 {code_GetGeneralDir}\config\loc\Fran?ais\colorfx,1.qm
#184 {code_GetGeneralDir}\config\loc\Fran?ais\colorfx,2.qm
#185 {code_GetGeneralDir}\config\loc\Fran?ais\tnzcore,1.qm
#186 {code_GetGeneralDir}\config\loc\Fran?ais\tnzcore,2.qm
#187 {code_GetGeneralDir}\config\loc\Fran?ais\tnztools,1.qm
#188 {code_GetGeneralDir}\config\loc\Fran?ais\tnztools,2.qm
#189 {code_GetGeneralDir}\config\loc\Fran?ais\toonz,1.qm
#190 {code_GetGeneralDir}\config\loc\Fran?ais\toonz,2.qm
#191 {code_GetGeneralDir}\config\loc\Fran?ais\toonzlib,1.qm
#192 {code_GetGeneralDir}\config\loc\Fran?ais\toonzlib,2.qm
#193 {code_GetGeneralDir}\config\loc\Fran?ais\toonzqt,1.qm
#194 {code_GetGeneralDir}\config\loc\Fran?ais\toonzqt,2.qm
#195 {code_GetGeneralDir}\config\loc\Italiano\colorfx,1.qm
#196 {code_GetGeneralDir}\config\loc\Italiano\colorfx,2.qm
#197 {code_GetGeneralDir}\config\loc\Italiano\tnzcore,1.qm
#198 {code_GetGeneralDir}\config\loc\Italiano\tnzcore,2.qm
#199 {code_GetGeneralDir}\config\loc\Italiano\tnztools,1.qm
#200 {code_GetGeneralDir}\config\loc\Italiano\tnztools,2.qm
#201 {code_GetGeneralDir}\config\loc\Italiano\toonz,1.qm
#202 {code_GetGeneralDir}\config\loc\Italiano\toonz,2.qm
#203 {code_GetGeneralDir}\config\loc\Italiano\toonzlib,1.qm
#204 {code_GetGeneralDir}\config\loc\Italiano\toonzlib,2.qm
#205 {code_GetGeneralDir}\config\loc\Italiano\toonzqt,1.qm
#206 {code_GetGeneralDir}\config\loc\Italiano\toonzqt,2.qm
#207 {code_GetGeneralDir}\config\loc\Russian (???????)\colorfx,1.qm
#208 {code_GetGeneralDir}\config\loc\Russian (???????)\colorfx,2.qm
#209 {code_GetGeneralDir}\config\loc\Russian (???????)\image,1.qm
#210 {code_GetGeneralDir}\config\loc\Russian (???????)\image,2.qm
#211 {code_GetGeneralDir}\config\loc\Russian (???????)\tnzcore,1.qm
#212 {code_GetGeneralDir}\config\loc\Russian (???????)\tnzcore,2.qm
#213 {code_GetGeneralDir}\config\loc\Russian (???????)\tnztools,1.qm
#214 {code_GetGeneralDir}\config\loc\Russian (???????)\tnztools,2.qm
#215 {code_GetGeneralDir}\config\loc\Russian (???????)\toonz,1.qm
#216 {code_GetGeneralDir}\config\loc\Russian (???????)\toonz,2.qm
#217 {code_GetGeneralDir}\config\loc\Russian (???????)\toonzlib,1.qm
#218 {code_GetGeneralDir}\config\loc\Russian (???????)\toonzlib,2.qm
#219 {code_GetGeneralDir}\config\loc\Russian (???????)\toonzqt,1.qm
#220 {code_GetGeneralDir}\config\loc\Russian (???????)\toonzqt,2.qm
#221 {code_GetGeneralDir}\config\loc\??\colorfx,1.qm
#222 {code_GetGeneralDir}\config\loc\??\colorfx,2.qm
#223 {code_GetGeneralDir}\config\loc\??\image,1.qm
#224 {code_GetGeneralDir}\config\loc\??\image,2.qm
#225 {code_GetGeneralDir}\config\loc\??\tnzcore,1.qm
#226 {code_GetGeneralDir}\config\loc\??\tnzcore,2.qm
#227 {code_GetGeneralDir}\config\loc\??\tnztools,1.qm
#228 {code_GetGeneralDir}\config\loc\??\tnztools,2.qm
#229 {code_GetGeneralDir}\config\loc\??\toonz,1.qm
#230 {code_GetGeneralDir}\config\loc\??\toonz,2.qm
#231 {code_GetGeneralDir}\config\loc\??\toonzlib,1.qm
#232 {code_GetGeneralDir}\config\loc\??\toonzlib,2.qm
#233 {code_GetGeneralDir}\config\loc\??\toonzqt,1.qm
#234 {code_GetGeneralDir}\config\loc\??\toonzqt,2.qm
#235 {code_GetGeneralDir}\config\loc\???\colorfx,1.qm
Error (Exception) "MoveFile failed; code 3.%n???????????" at address 0048BFFC

linsui avatar Sep 27 '19 05:09 linsui

It works for me. Seems like codepage error (there're some ? in the log, which are unicode chars.

niheaven avatar Sep 27 '19 08:09 niheaven

Could you support extract_dir in all installer.type ?

Here is a use case.

servo.json
    "version": "nightly",
    "homepage": "https://servo.org",
    "description": "A modern, high-performance browser.",
    "architecture": {
        "64bit": {
            "url": "https://download.servo.org/nightly/windows-msvc/servo-latest.exe"
        }
    },
    "extract_dir": "PFiles\\Mozilla Research\\Servo Tech Demo", // This does not work.
    "installer": {
        "type": "wix",
        "script": "Move-Item \"$dir\\PFiles\\Mozilla Research\\Servo Tech Demo\\*\" \"$dir\""
    },
    "bin": "servo.exe",
    "shortcuts": [
        [
            "servo.exe",
            "Servo"
        ]
    ]
}

linsui avatar Oct 16 '19 15:10 linsui

Could you support extract_dir in all installer.type ?

This will lead to too complicated manifest for these installer.type, since it's difficult to know when extract_dir is needed. post_install is more readable.

niheaven avatar Oct 22 '19 10:10 niheaven

@r15ch13 This could be merged and tested, and is compatible with current codes, and then I'll resolve merging conflicts with #3534

niheaven avatar Oct 22 '19 10:10 niheaven

There is disadvantage from installer.type migration

url: url
hash: hash
innosetup: true
architecture:
  64bit:
    installer:
      script: do something
  32bit:
    installer:
      script: do something

With these changes there is not possible to do this:

url: url
hash: hash
installer:
  type: inno
architecture:
  64bit:
    installer:
      script: do something
  32bit:
    installer:
      script: do something

You need to duplicate these lines to both architectures

url: url
hash: hash
installer:
  type: inno
architecture:
  64bit:
    installer:
      type: inno
      script: do something
  32bit:
    installer:
      type: inno
      script: do something

Ash258 avatar Oct 22 '19 11:10 Ash258

The first installer.type is needless, and you need two arch-spec installer.type for different arches. Or you can use innosetup:true which is convert to installer.type:inno at runtime (for any arch), but give some warnings :smile:

Or why not use arch.pre_install or arch.post_install? installer.type is handled in extraction step.

PS. For most inno-setup archive, new added installer.include and installer.exclude are more usable. See manifest examples (gimp, scilab) for ref.

niheaven avatar Oct 22 '19 11:10 niheaven

https://github.com/ScoopInstaller/Main/pull/512 doesn't work with this. Only the first url will be extracted. Any workarounds? For example,

    "installer": {
        "type": [
            "inno",
            "inno"
        ]
    }

?

linsui avatar Oct 26 '19 09:10 linsui

https://github.com/lukesampson/scoop-extras/pull/2264/commits/7b34c194694d66a8f3499e8638290af31bfab0ca is the reason why i would rather have separate extraction property instead of adding it into installer and duplicating into each architecture with in this case litle bit different code, but mainly in other cases.

Also installer property is not reflecting it's real usage. Since installer is happening after pre_install, which is happening after real extraction.

Ash258 avatar Nov 26 '19 13:11 Ash258

Since they are 'installer's, I put the params in installer. I don't think it's a good idea that adding a new extraction property in the manifests, right?

In the installer property, installer.type is invoked during extraction step, while other sub-properties are invoked after pre_install. This may be confused, but I couldn't find anywhere else to place them properly.

I got an idea that we may patch arch_specific in lib\manifest.ps1 to let it support multiple properties in architecture or not, we just glue these same properties and use them all. This will shorten some manifests.

niheaven avatar Nov 28 '19 10:11 niheaven

Since this PR is a mixture of fixing, refactoring and new features, I'll try to separate the functionality of each line of code and keep this as a pure feature adding one.

niheaven avatar Jan 08 '22 07:01 niheaven