Skip to content

Commit

Permalink
Added standalone / portable installer on Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
lelegard committed Jun 17, 2017
1 parent 12ec59c commit 64f880a
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 10 deletions.
12 changes: 11 additions & 1 deletion windows/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Be sure to select the option "MinGW" in the "Tools" section (this option is disa
- build-windows.ps1 : PowerShell script to build the installer.
- qtlinguist.nsi : NSIS (Nullsoft Scriptable Installation System) script.

### Building the Qt Linguist installer
### Building the Qt Linguist installers

Execute the script `build-windows.ps1` from PowerShell.

Expand Down Expand Up @@ -40,3 +40,13 @@ Version of Qt Linguist. The default is extracted from the Qt directory name.
Do not wait for the user to press <enter> at end of execution. By default,
execute a "pause" instruction at the end of execution, which is useful
when the script was run from Windows Explorer.

### Using the installers

The script generates two installers, a classical one and a standalone / portable one.

The classical installer is the `.exe` file. Execute it to install Qt Linguist.

The standalone / portable installer is the `.zip` file. It is meant to be used
be users without administration privileges on the Windows system. Simply unzip
the file anywhere. To run Qt Linguist, simply execute `QtLinguist\bin\linguist.exe`.
140 changes: 132 additions & 8 deletions windows/build-windows.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,116 @@ function Search-File ([string]$File, $DirList)
return $path
}

#-----------------------------------------------------------------------------

<#
.SYNOPSIS
Create a zip file from any files piped in.
.PARAMETER Path
The name of the zip archive to create.
.PARAMETER Root
Store directory names in the zip entries. Use the same hierarchy as input
files but strip the root from their full name. If unspecified, create a
flat archive of files without hierarchy.
.PARAMETER Force
If specified, delete the zip archive if it already exists.
.EXAMPLE
PS > dir *.ps1 | New-ZipFile scripts.zip
Copies all PS1 files in the current directory to scripts.zip
.EXAMPLE
PS > "readme.txt" | New-ZipFile docs.zip
Copies readme.txt to docs.zip
.NOTES
Initial version from Windows PowerShell Cookbook (O'Reilly)
by Lee Holmes (http://www.leeholmes.com/guide)
with additional options.
This function requires Microsoft .NET Framework version 4.5 or higher.
See http://www.microsoft.com/en-us/download/details.aspx?id=30653 or, for
a full offline package, http://go.microsoft.com/fwlink/?LinkId=225702
(dotnetfx45_full_x86_x64.exe).
#>
function New-ZipFile
{
[CmdletBinding()]
param(
[Parameter(Mandatory=$true,Position=1)][String] $Path,
[Parameter(Mandatory=$false,Position=2)][String] $Root = $null,
[Parameter(ValueFromPipeline=$true)] $Input,
[Switch] $Force
)

Set-StrictMode -Version 3

# Check if the file exists already.
$ZipName = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path)
if (Test-Path $ZipName) {
if ($Force) {
Remove-Item $ZipName -Force
}
else {
# Zip file exists and no -Force option, generate an error.
throw "$ZipName already exists."
}
}

# Build the root path, i.e. the path to strip from entries directory path.
if ($Root) {
$Root = (Get-Item $Root).FullName
}

# Add the DLL that helps with file compression.
# This requires .NET 4.5 (FileNotFoundException on previous releases).
Add-Type -Assembly System.IO.Compression.FileSystem

try {
# Open the Zip archive
$archive = [System.IO.Compression.ZipFile]::Open($ZipName, "Create")

# Go through each file in the input, adding it to the Zip file specified
foreach ($file in $Input) {
$item = $file | Get-Item
# Skip the current file if it is the zip file itself
if ($item.FullName -eq $ZipName) {
continue
}
# Skip directories
if ($item.PSIsContainer) {
continue
}
# Compute entry name in archive.
if ($Root -and $item.FullName -like "$Root\*") {
$name = $item.FullName.Substring($Root.Length + 1)
}
else {
$name = $item.Name
}
# Add the file to the archive.
$null = [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($archive, $item.FullName, $name)
}
}
finally {
# Close the file
$archive.Dispose()
$archive = $null
}
}

#-----------------------------------------------------------------------------

# Get the project directories.

$RootDir = (Split-Path -Parent $PSScriptRoot)
Expand Down Expand Up @@ -203,8 +313,8 @@ while (!$VcredistDir -and $path -ne "") {
}
}
if ($VcredistDir) {
# vcredist directory found, search executables here
$exe = @(Get-ChildItem $VcredistDir -Filter *.exe)
# vcredist directory found, search executables here.
$exe = @(Get-ChildItem $VcredistDir -Filter *.exe | Where-Object Name -NotLike *x64.exe)
if ($exe.Count -eq 1) {
$VcredistExe = $exe[0].FullName
$VcredistName = (Split-Path -Leaf $VcredistExe)
Expand All @@ -228,21 +338,35 @@ if (Test-Path $TempDir) {
# The rest of the script is in a try block to ensure the cleanup of the temporary directory.

try {
$TempRootDir = (Join-Path $TempDir "QtLinguist")
[void] (New-Item -ItemType Directory -Force $TempRootDir)
$TempBinDir = (Join-Path $TempRootDir "bin")
[void] (New-Item -ItemType Directory -Force $TempBinDir)

# Copy Linguist in temporary directory and "deploy" dependant modules.
Copy-Item $LinguistExe $TempDir
& $WinDeployExe $TempDir --release --no-quick-import --no-system-d3d-compiler --no-webkit2 --no-angle --no-opengl-sw
Copy-Item (Join-Path $QtBinDir lconvert.exe) $TempDir
Copy-Item (Join-Path $QtBinDir lrelease.exe) $TempDir
Copy-Item (Join-Path $QtBinDir lupdate.exe) $TempDir
Copy-Item $LinguistExe $TempBinDir
& $WinDeployExe $TempBinDir --release --no-quick-import --no-system-d3d-compiler --no-webkit2 --no-angle --no-opengl-sw
Copy-Item (Join-Path $QtBinDir lconvert.exe) $TempBinDir
Copy-Item (Join-Path $QtBinDir lrelease.exe) $TempBinDir
Copy-Item (Join-Path $QtBinDir lupdate.exe) $TempBinDir

# Build the installer.
& $NsisExe.FullName `
"/DProductVersion=$Version" `
"/DRootDir=$RootDir" `
"/DBinDir=$TempDir" `
"/DBinDir=$TempBinDir" `
"/DVcredistExe=$VcredistExe" `
"/DVcredistName=$VcredistName" `
"$($NsisScript.FullName)"

# Copy VC++ redistributable libraries.
$TempRedistDir = (Join-Path $TempRootDir "vcredist")
[void] (New-Item -ItemType Directory -Force $TempRedistDir)
Copy-Item $VcredistExe $TempRedistDir

# Build standalone installer.
$ZipInstaller = (Join-Path $InstallerDir "QtLinguist-Standalone-$Version.zip")
Get-ChildItem -Recurse $TempRootDir | New-ZipFile $ZipInstaller -Force -Root $TempDir
}
finally {
# Cleanup temporary directory.
Expand Down
2 changes: 1 addition & 1 deletion windows/qtlinguist.nsi
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ Section "Install"
WriteUninstaller "$INSTDIR\QtLinguistUninstall.exe"

; Install 'vcredist' (Visual C++ Redistributable) if available.
!if ${VcredistExe} != ""
!if "${VcredistExe}" != ""
SetOutPath "$INSTDIR\vcredist"
File "${VcredistExe}"
ExecWait '"$INSTDIR\vcredist\${VcredistName}" /install /quiet /norestart'
Expand Down

0 comments on commit 64f880a

Please sign in to comment.