Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
wants to merge 18 commits into
base: develop
Choose a base branch
from

Conversation

niheaven
Copy link
Member

@niheaven niheaven commented Jun 10, 2019

  • 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: multi: Use installer.type for python and mro Main#121, multi: Use installer.type for nsis and inno type apps Extras#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"
},

lib/manifest.ps1 Outdated Show resolved Hide resolved
lib/manifest.ps1 Outdated Show resolved Hide resolved
lib/manifest.ps1 Show resolved Hide resolved
lib/install.ps1 Outdated Show resolved Hide resolved
lib/decompress.ps1 Outdated Show resolved Hide resolved
lib/decompress.ps1 Outdated Show resolved Hide resolved
lib/decompress.ps1 Outdated Show resolved Hide resolved
@niheaven
Copy link
Member Author

niheaven commented Jun 19, 2019

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

Fixed.

@niheaven
Copy link
Member Author

niheaven commented Jul 7, 2019

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 niheaven changed the title feat(install): Add unpacker for 'wix' and 'nsis' installer feat(install): Add unpacker for 'wix', 'nsis' and 'inno' installer Jul 15, 2019
@linsui
Copy link
Contributor

linsui commented Sep 1, 2019

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

lib/install.ps1 Outdated Show resolved Hide resolved
@linsui
Copy link
Contributor

linsui commented Oct 16, 2019

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"
        ]
    ]
}

@niheaven
Copy link
Member Author

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
Copy link
Member Author

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

@Ash258
Copy link
Contributor

Ash258 commented Oct 22, 2019

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

@niheaven
Copy link
Member Author

niheaven commented Oct 22, 2019

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 😄

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.

@linsui
Copy link
Contributor

linsui commented Oct 26, 2019

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

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

?

@Ash258
Copy link
Contributor

Ash258 commented Nov 26, 2019

ScoopInstaller/Extras@7b34c19 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.

@niheaven
Copy link
Member Author

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
Copy link
Member Author

niheaven commented Jan 8, 2022

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants