Skip to content

Commit

Permalink
Added a PowerShell script for easy installation.
Browse files Browse the repository at this point in the history
Bump to 0.3.0.
  • Loading branch information
RobotsOnDrugs committed Jun 21, 2024
1 parent 334cf40 commit adbc561
Show file tree
Hide file tree
Showing 5 changed files with 425 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "moo_fuck_screen_connect"
version = "0.2.1"
version = "0.3.0"
edition = "2021"

[dependencies]
Expand Down
77 changes: 77 additions & 0 deletions install.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
##Requires -RunAsAdministrator

# There's a lot of null-passing and null-checking. This sucks, but I'm not sure how to better handle bad states in PowerShell.
# It's a lot clunkier and awkward to pass around exceptions in PS than in C# or with Result<T> in Rust, but this script would probably take longer to write in Rust. >_>
# Feel free to open an issue if you have a better way. It's possibly just a skill issue since I'm a lot less familiar with PS scripting.

<#
.DESCRIPTION
Installs FuckScreenConnect either from the current directory or updates it from a GitHub release.
If there is an error, regardless of any options specified, and with the exception of missing files or the scheduled task, the script will immediately halt and any issues must then be resolved manually.
.PARAMETER InstallationPath
Required if there is no existing installation or if the existing installation is broken.
The full path to the main FSC executable where it is to be installed. You may name this executable whatever you wish as long as the extension is .exe.
If there is an existing installation, it will be fully uninstalled.
.PARAMETER Type [Install | Uninstall]
Optional; defaults to Install.
Install copies required files to the installation directory and creates a scheduled task. If -InstallationPath is not set, only the binaries will be copied, leaving your configuration as-is, which is basically just an update.
Uninstall prompts for confirmation and then deletes any installed files and the scheduled task as well as any installation configuration.
.PARAMETER InstallationSource [ GitHub | Local | Auto ]
Optional; defaults to Auto. Support for installing/updating via GitHub is currently unimplemented but planned in future releases, so it only performs a local installation.
Auto will compare the version of the installed binary to the latest release on GitHub and to the binary in the same directory in this script, and the newest one will be used. In the case of a tie, doing nothing is preferred over a local install, which is preferred over grabbing from GitHub.
If Local is used, installation will proceed from the current directory regardless of the installed or GitHub versions, and abort if there is nothing to install from the current directory. GitHub will always pull the latest release on GitHub and install it.
.PARAMETER Force
Optional; unset by default.
If set, (un)installation will clobber or forcibly delete any existing installations with no confirmation.
.PARAMETER NonInteractive
Optional; unset by default.
If set, all confirmations are suppressed and all defaults for confirmations are used. Additionally, no debug or information messages other than "Starting." and "Finished." will be shown.
Existing installations that do not need to be updated will not be overwritten unless -Force is set.
.PARAMETER ShowDebugMessages
Optional; unset by default. If set, debug messages are shown. Primarily meant for troubleshooting and developer use, and the messages shown are subject to change.
#>

param
(
[string]$InstallationPath = $null,
[string][ValidateSet('Install','Uninstall')]$Type = 'Install',
[string][ValidateSet('Auto','Local', 'GitHub')]$InstallationSource = 'Auto',
[Switch]$Force,
[Switch]$NonInteractive,
[Switch]$ShowDebugMessages
)

$compatible = ($PSVersionTable.PSVersion.Major -eq 5) -and ($PSVersionTable.PSVersion.Minor -eq 1);
if (-not $compatible) { Write-Error "This script must be run with PowerShell 5.1 and is not tested on other versions." }

$ErrorActionPreference = 'Stop'

. .\install_modules\logging.ps1
Write-Log -Level DEBUG -Message 'Logging script run.'
Write-Log -Level DEBUG -Message "Running PowerShell $($PSVersionTable.PSVersion)"
. .\install_modules\fsc_functions.ps1
Write-Log -Level DEBUG -Message 'FSC functions script run.'
Write-Log -Level INFO -Message 'Starting.'

if ($($InstallationPath.Length) -eq 0) { $install_path = $null }
else { $install_path = $InstallationPath }
switch ($Type)
{
'Install'
{
Write-Log -Level INFO -Message "Installing FSC."
Uninstall-Fsc $Force $install_path
Install-Fsc $InstallationSource $install_path !$Force
break
}
'Uninstall'
{
Write-Log -Level INFO -Message "Uninstalling FSC."
Uninstall-Fsc $true $install_path
break
}
default { Write-Log -Level ERROR -Message "$Type is not a valid installation type." }
}

Write-Log -Level INFO -Message 'Finished.'
Wait-Logging
61 changes: 61 additions & 0 deletions install_modules/external_tools.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
$PsExecHash = '3E2272B916DA4BE3C120D17490423230AB62C174'
$FscTempFolder = Join-Path $env:TEMP "fsc_temp"

function Get-PsExec
{
$PsExecPath = (Get-Command psexec).Source
$hash = Compare-FileHash $PsExecPath
# TODO: examine targets of Chocolatey shims to avoid downloading when there's a perfectly good copy laying around.
# Hint: spawn `C:\ProgramData\chocolatey\bin\PsExec.exe --shimgen-help` via [System.Diagnostics.ProcessStartInfo]::new()
if ($hash -eq $PsExecHash)
{
Write-Log -Level DEBUG -Message 'PsExec was found in the path.'
Remove-Item -Recurse $FscTempFolder -Force -ErrorAction SilentlyContinue
return $PsExecPath
}

$PsExecPath = Join-Path $PWD 'PsExec.exe'
$hash = Compare-FileHash $PsExecPath
if ($hash -eq $PsExecHash)
{
Write-Log -Level DEBUG -Message 'PsExec was found in the current directory.'
Remove-Item -Recurse $FscTempFolder -Force -ErrorAction SilentlyContinue
return $PsExecPath
}

New-Item -Type Directory $FscTempFolder -Force | Out-Null
Push-Location $FscTempFolder
$PsExecPath = Join-Path $PWD 'PSTools\PsExec.exe'

$valid_psexec_in_temp = $hash -eq $PsExecHash
switch ($valid_psexec_in_temp)
{
$true
{
Pop-Location
Copy-Item -Path $PsExecPath -Destination '.' -Force
}
$false
{
New-Item -Type Directory '.\PSTools' -Force | Out-Null
$psexec_url = "https://download.sysinternals.com/files/PSTools.zip"
$curl = $(Get-Command curl).Source
if ($null -ne $curl) { & $curl -k -s $psexec_url -o PSTools.zip }
else { Invoke-WebRequest -Uri $psexec_url -OutFile 'PSTools.zip' }

Expand-Archive -LiteralPath '.\PSTools.zip' -DestinationPath '.\PSTools' -Force | Out-Null
$psexec_exe_path = Join-Path $FscTempFolder 'PSTools\PsExec.exe'
Pop-Location
Copy-Item -Path $psexec_exe_path -Destination '.' -Force
$PsExecPath = Join-Path $PWD 'PsExec.exe'
}
}
Remove-Item -Recurse $FscTempFolder -Force
return $PsExecPath
}

function Compare-FileHash
{
param([String]$FilePath)
return (Get-FileHash -Algorithm SHA1 $FilePath -ErrorAction SilentlyContinue).Hash -eq $PsExecHash
}
Loading

0 comments on commit adbc561

Please sign in to comment.