tridactyl/native/win_install.ps1
Oliver Blanthorn ef9f02d0da
Make native{install,update} use corresponding tag for stable build
Beta builds will always use most recent messenger, which I think is probably fair;
old beta builds are unsupported.
2019-05-31 15:02:05 +01:00

588 lines
16 KiB
PowerShell

Param (
[switch]$Uninstall = $false,
[switch]$NoPython= $false,
[string]$DebugDirBase = "",
[string]$InstallDirBase = "",
[string]$Tag = "1.15.0"
)
#
# Global constants
#
$global:InstallDirName = ".tridactyl"
$global:MessengerBinPyName = "native_main.py"
$global:MessengerBinExeName = "native_main.exe"
$global:MessengerBinWrapperFilename = "native_main.bat"
$global:MessengerManifestFilename = "tridactyl.json"
$global:PythonVersionStr = "^3\."
$global:WinPython3Command = "py -3 -u"
$global:MessengerManifestReplaceStr = "REPLACE_ME_WITH_SED"
$global:PowerShellMinimumVersion = 3
$git_repo_owner = "tridactyl"
$git_repo_branch = $Tag
$git_repo_proto = "https"
$git_repo_host = "raw.githubusercontent.com"
$git_repo_name = "tridactyl"
$git_repo_dir = "native"
$global:MessengerFilesHttpUriBase = `
[string]::Format("{0}://{1}/{2}/{3}/{4}/{5}",
$git_repo_proto,
$git_repo_host,
$git_repo_owner,
$git_repo_name,
$git_repo_branch,
$git_repo_dir
)
$global:MessengerExeHttpUriBase = "https://tridactyl.cmcaine.co.uk/betas"
$global:MessengerManifestRegistryPath = `
"HKCU:\Software\Mozilla\NativeMessagingHosts\tridactyl"
$global:Uninstall = $Uninstall
$global:NoPython= $NoPython
$global:InstallDirBase = $InstallDirBase.Trim()
$global:DebugDirBase = $DebugDirBase.Trim()
function Set-PowerShellVersion() {
$requiredPowerShellVersion = $global:PowerShellMinimumVersion
$currentPowerShellVersion = [int]`
($PSVersionTable.PSVersion.Major)
if ($currentPowerShellVersion -lt $requiredPowerShellVersion) {
$msg = [string]::Format("{0} >= '{1}' {2}, '{3}' {4}",
" - PowerShell major version",
$requiredPowerShellVersion,
"required",
$currentPowerShellVersion,
"found, quitting ..."
)
Write-Host "[+] Installation failed. :-("
Write-Host $msg
exit -1
}
}
function Set-TlsVersion() {
[Net.ServicePointManager]::SecurityProtocol =
[Net.SecurityProtocolType]::Tls12 -bOr `
[Net.SecurityProtocolType]::Tls11
}
function Get-PythonVersionStatus() {
try {
$pythonVersion = Invoke-Expression `
"$global:WinPython3Command -c ""import sys; print(sys.version)"""
} catch {
$pythonVersion = ""
}
if ($pythonVersion -match $global:PythonVersionStr) {
return $true
} else {
return $false
}
}
function Set-MessengerUninstall() {
Write-Host "[+] Uninstalling Tridactyl native-messenger ..."
$messengerBinPath = Get-MessengerBinPath
$messengerBinWrapperPath = Get-MessengerBinWrapperPath
$messengerManifestPath = Get-MessengerManifestPath
$result = Remove-TridactylPath $messengerBinPath
$result = Remove-TridactylPath $messengerBinWrapperPath
$result = Remove-TridactylPath $messengerManifestPath
$result1 = Test-TridactylPath $messengerBinPath
$result2 = Test-TridactylPath $messengerBinWrapperPath
$result3 = Test-TridactylPath $messengerManifestPath
$result4 = Remove-MessengerManifestRegistry
if (($result1 -eq $false) `
-and ($result2 -eq $false) `
-and ($result3 -eq $false) `
-and ($result4 -eq $true)) {
Write-Host "[+] Uninstallation successful! :-)"
} else {
Write-Host "[+] Uninstallation failed. :-("
}
}
function Remove-TridactylPath() {
Param([string]$path)
if (! (Test-Path $path)) {
return
}
Write-Host `
-NoNewline `
" - Removing $path "
$result = Remove-Item `
-Force `
-Recurse `
-Path $path
if ($result -eq 0) {
Write-Host "was successful!"
return $true
}
else {
Write-Host "failed."
return $false
}
}
function Test-TridactylPath() {
Param([string]$path)
Write-Host `
-NoNewline `
" - Testing $path "
if((Test-Path $path)) {
Write-Host "was successful!"
return $true
}
else {
Write-Host "failed."
return $false
}
}
function Get-MessengerInstallDir() {
if (($InstallDirBase.Length -gt 0) `
-and (Test-Path $InstallDirBase.Trim())) {
$messengerInstallDir = [string]::Format("{0}\{1}",
$global:InstallDirBase,
$global:InstallDirName
)
} else {
$messengerInstallDir = [string]::Format("{0}\{1}",
$env:USERPROFILE,
$global:InstallDirName
)
}
return $messengerInstallDir.Trim()
}
function Set-InstallDir() {
$messengerInstallDir = Get-MessengerInstallDir
Write-Host "[+] Preparing $messengerInstallDir ..."
If(! (Test-Path $messengerInstallDir)) {
New-Item -ItemType Directory `
-Force `
-Path $messengerInstallDir | Out-Null
} else {
Write-Host `
" - $messengerInstallDir exists, moving on ..."
}
$result = Test-TridactylPath $messengerInstallDir
if ($result -eq $true) {
Write-Host `
" - Creating $messengerInstallDir was successful!"
return $true
} else {
Write-Host `
" - Creating $messengerInstallDir failed, quitting ..."
exit -1
}
}
function Get-MessengerBinName() {
$messengerBinName = $global:MessengerBinPyName
if ($global:NoPython -eq $true) { # system doesn't have python3
$messengerBinName = $global:MessengerBinExeName
}
Return $messengerBinName
}
function Get-MessengerBinPath() {
$messengerInstallDir = Get-MessengerInstallDir
$messengerBinName = Get-MessengerBinName
$native_messenger_binary_path = [string]::Format("{0}\{1}",
$messengerInstallDir,
$messengerBinName)
Return $native_messenger_binary_path.Trim()
}
function Get-MessengerBinUri() {
$downloadStartTime = (Get-Date `
-Date ((Get-Date).ToUniversalTime()) `
-UFormat %s)
$messengerBinName = Get-MessengerBinName
if ($global:NoPython -eq $true) { # system doesn't have python3
$messengerBinUri = [string]::Format("{0}/{1}",
$global:MessengerExeHttpUriBase,
$messengerBinName
)
} else {
$messengerBinUri = [string]::Format("{0}/{1}?{2}",
$global:MessengerFilesHttpUriBase,
$messengerBinName,
$downloadStartTime)
}
Return $messengerBinUri.Trim()
}
function Set-MessengerBin() {
$messengerBinPath = Get-MessengerBinPath
$messengerBinUri = Get-MessengerBinUri
if ($global:DebugDirBase.Length -gt 0) {
$messengerBinName = Get-MessengerBinName
$srcPath = [string]::Format("{0}\{1}",
$global:DebugDirBase,
$messengerBinName)
Write-Host "[+] Copying $srcPath ..."
Copy-Item `
-Path $srcPath `
-Destination $messengerBinPath `
-Force `
} else {
Write-Host "[+] Downloading $messengerBinUri ..."
try {
Set-TlsVersion
Invoke-WebRequest `
-Uri $messengerBinUri `
-OutFile $messengerBinPath
} catch {
Write-Host `
"Invoke-WebRequest Exception:" `
$_.Exception.GetType().FullName, $_.Exception.Message
Write-Host `
"Invoke-WebRequest StatusCode:" `
$_.Exception.Response.StatusCode.value__
Write-Host `
"Invoke-WebRequest StatusDescription:" `
$_.Exception.Response.StatusDescription
Write-Host "[+] Downloading failed, quitting ..."
exit -1
}
}
$result = Test-TridactylPath -Path $messengerBinPath
if ($result -eq $true) {
Write-Host `
" - Creating $messengerBinPath was successful!"
return $true
} else {
Write-Host `
" - Creating $messengerBinPath failed, quitting ..."
exit -1
}
}
function Get-MessengerBinWrapperPath() {
$messengerInstallDir = Get-MessengerInstallDir
$messengerBinWrapperPath = [string]::Format("{0}\{1}",
$messengerInstallDir,
$global:MessengerBinWrapperFilename)
Return $messengerBinWrapperPath.Trim()
}
function Set-MessengerBinWrapper() {
$messengerBinName = Get-MessengerBinName
$messengerBinWrapperPath = Get-MessengerBinWrapperPath
if ($global:NoPython -eq $false) { # system has python3
$messengerWrapperContent = @"
@echo off
call $global:WinPython3Command .\$messengerBinName
"@
} else { ## system does _not_ have python3
$messengerWrapperContent = @"
@echo off
call .\$messengerBinName
"@
}
Write-Host "[+] Preparing $messengerBinWrapperPath ..."
$messengerWrapperContent `
| Out-File `
-Encoding ascii `
-FilePath $messengerBinWrapperPath
$result = Test-TridactylPath -Path $messengerBinWrapperPath
if ($result -eq $true) {
$msg = [string]::Format(
" - Creating {0} was successful!",
$messengerBinWrapperPath)
Write-Host $msg
return $true
} else {
$msg = [string]::Format(
" - Creating {0} failed, quitting ...",
$messengerBinWrapperPath)
Write-Host $msg
exit -1
}
}
function Get-MessengerManifestPath() {
$messengerInstallDir = Get-MessengerInstallDir
$messengerManifestPath = [string]::Format("{0}\{1}",
$messengerInstallDir,
$global:MessengerManifestFilename)
return $messengerManifestPath.Trim()
}
function Get-MessengerManifestUri() {
$downloadStartTime = (Get-Date `
-Date ((Get-Date).ToUniversalTime()) `
-UFormat %s)
$messengerManifestUri = [string]::Format("{0}/{1}?{2}",
$global:MessengerFilesHttpUriBase,
$global:MessengerManifestFilename,
$downloadStartTime)
return $messengerManifestUri.Trim()
}
function Set-MessengerManifest() {
$messengerManifestPath = Get-MessengerManifestPath
$messengerManifestUri = Get-MessengerManifestUri
$result = $false
if ($global:DebugDirBase.Length -gt 0) {
$srcPath = [string]::Format("{0}\{1}",
$global:DebugDirBase,
$global:MessengerManifestFilename)
Write-Host "[+] Copying $srcPath ..."
Copy-Item `
-Path $srcPath `
-Destination $messengerManifestPath `
-Force `
} else {
Write-Host "[+] Downloading $messengerManifestUri ..."
try {
Set-TlsVersion
Invoke-WebRequest `
-Uri $messengerManifestUri `
-OutFile $messengerManifestPath
} catch {
Write-Host `
"Invoke-WebRequest StatusCode:" `
$_.Exception.Response.StatusCode.value__
Write-Host `
"Invoke-WebRequest StatusDescription:" `
$_.Exception.Response.StatusDescription
Write-Host " - Downloading failed, quitting ..."
exit -1
}
}
$result = Test-TridactylPath -Path $messengerManifestPath
if ($result -eq $true) {
$msg = [string]::Format(
" - Creating {0} was successful!",
$messengerManifestPath)
Write-Host $msg
} else {
$msg = [string]::Format(
" - Creating {0} failed, quitting ...",
$messengerManifestPath)
Write-Host $msg
exit -1
}
(Get-Content `
$messengerManifestPath).replace( `
$MessengerManifestReplaceStr, `
$MessengerBinWrapperFilename) `
| Set-Content -Encoding ascii $messengerManifestPath
$found_pattern = (Select-String `
-Path $messengerManifestPath `
-Pattern $MessengerManifestReplaceStr `
-CaseSensitive `
| Select-Object Line)
if (! $found_pattern) {
Write-Host `
" - Patching $messengerManifestPath was successful!"
}
return $result
}
function Get-MessengerManifestRegistry(){
$msg = [string]::Format("[+] Getting registry key {0} ...",
$global:MessengerManifestRegistryPath)
Write-Host $msg
$registry = Get-Item `
-Path "$global:MessengerManifestRegistryPath" `
-ErrorAction SilentlyContinue
return $registry
}
function Get-MessengerManifestRegistryValue(){
$msg = [string]::Format( `
"[+] Getting (Default) registry value {0} ...",
$global:MessengerManifestRegistryPath)
Write-Host $msg
$registryKey = Get-MessengerManifestRegistry
$registryValue = ""
if ($registryKey) {
$registryValue = $registryKey."(Default)" `
-eq $messengerManifestPath
}
return $registryValue
}
function Remove-MessengerManifestRegistry() {
$msg = [string]::Format("[+] Removing registry key {0} ...",
$global:MessengerManifestRegistryPath)
Write-Host $msg
Remove-Item `
-Path "$global:MessengerManifestRegistryPath" `
-Force `
-ErrorAction SilentlyContinue
$registryExists = Get-MessengerManifestRegistry
if (! $registryExists) {
Write-Host " - Removing registry was successful!"
return $true
} else {
Write-Host " - Removing registry failed, quitting ..."
exit -1
}
}
function Set-MessengerManifestRegistry() {
$messengerManifestPath = Get-MessengerManifestPath
$msg = [string]::Format("[+] Adding registry key {0} ...",
$global:MessengerManifestRegistryPath)
Write-Host $msg
New-Item `
-Path $global:MessengerManifestRegistryPath `
-Force | Out-Null
New-ItemProperty `
-Path $global:MessengerManifestRegistryPath `
-Name "(Default)" `
-Value $messengerManifestPath `
-Force | Out-Null
if ((Get-ItemProperty `
-Path $MessengerManifestRegistryPath)."(Default)" `
-eq $messengerManifestPath) {
Write-Host " - Adding registry was successful!"
return $true
} else {
Write-Host " - Adding registry failed, quitting ..."
exit -1
}
}
function Set-MessengerInstall() {
# Check if system has Python 3, unless user set # the
# `-NoPython` flag
if ($global:NoPython -eq $false) {
Write-Host "[+] Looking for Python 3 ..."
$pythonVersionStatus = Get-PythonVersionStatus
if (! $pythonVersionStatus) {
Write-Host " - Python 3 not found, will use EXE ..."
$global:NoPython = $true
} else {
$pythonPath = Get-Command "py" `
| Select-Object -ExpandProperty "Source"
Write-Host " - Python 3 found at: $pythonPath"
}
}
# Prepare `.tridactyl` directory
$result = Set-InstallDir
# Prepare `native_main.{py,exe}`
if ($result -eq $true) {
$result = Set-MessengerBin
}
# Prepare `native_main.bat`
if ($result -eq $true) {
$result = Set-MessengerBinWrapper
}
# Prepare `tridactyl.json`
if ($result -eq $true) {
$result = Set-MessengerManifest
}
## Add registry entry
if ($result -eq $true) {
$result = Set-MessengerManifestRegistry
}
#
# If we are here passing all the checks above, installation is
# highly likely to have gone as expected. Let's do some final
# sanity checks before declaring "victory"!
#
Write-Host "[+] Cross-checking everything ..."
$result1 = Test-TridactylPath (Get-MessengerManifestPath)
$result2 = Test-TridactylPath (Get-MessengerBinPath)
$result3 = Test-TridactylPath (Get-MessengerBinWrapperPath)
$result4 = Get-MessengerManifestRegistryValue
if (($result1 -eq $true) `
-and ($result2 -eq $true) `
-and ($result3 -eq $true) `
-and ($result4)) {
Write-Host "[+] Installation successful!"
Write-Host " - Run ':native' in Firefox to cross-check. :-)"
} else {
Write-Host "[+] Installation failed. :-("
}
}
## Perform `Uninstall` if requested
if ($global:Uninstall) {
Set-MessengerUninstall
exit 0
}
Set-PowerShellVersion
Set-MessengerInstall