diff --git a/README.md b/README.md index ad3c51c..6172565 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,15 @@ # Tunic -Install Linux over or alongside an existing Windows install, straight from Windows, without requiring to boot from external media like a flash drive or making BIOS configuration changes. +Install Linux over or alongside an existing Windows install, straight from Windows, +without requiring to boot from external media like a flash drive or making BIOS configuration changes. -![Alt text](https://i.imgur.com/VOhRiGh.png) ![Alt text](https://i.imgur.com/YNNt4HZ.png) ![Alt text](https://i.imgur.com/9P8auhO.png) - -### Requirements - -* Windows 7, 8, 8.1, or 10, 64 bit -* Single drive hosting the C: volume -* UEFI (supports secure boot) -* At least 4 GB RAM -* At least 15 GB of free disk space on C: -* Administrator user permissions -* Internet access -* AC Wall Power +![Alt text](https://i.imgur.com/VOhRiGh.png) +![Alt text](https://i.imgur.com/YNNt4HZ.png) +![Alt text](https://i.imgur.com/9P8auhO.png) ### What Tunic Does -* Validates your system is compatible with Tunic. +* Validates your system meets Tunic requirements. * Asks all questions at beginning (so you don't have to babysit the install). * Offers to convert a MBR disk to UEFI. * Offers full disk overwrite or dual boot arrangement. @@ -33,11 +25,23 @@ Install Linux over or alongside an existing Windows install, straight from Windo See the [TODO](doc/TODO.md) for ideas for future versions. +### Requirements + +* Windows 10, 64 bit +* Single drive hosting the C: volume +* UEFI (supports secure boot) +* At least 4 GB RAM +* At least 15 GB of free disk space on C: +* Administrator user permissions +* Internet access +* AC Wall Power + ### Limitations * Currently, Tunic only installs official flavors of Ubuntu and Linux Mint. -* We are working on testing Windows 7 and 8, MBR, and support for other Debian/Ubuntu based Linux distros. +* We are working on Windows 7 and 8, MBR, and support for other Debian/Ubuntu based Linux distros. * Error handling needs improvement. +* Due to the nature of what Tunic does, it may show up as a false positive on some malware scans. ### More information @@ -59,7 +63,9 @@ No, really. Backup your data. ### Usage -1. Download and run the [latest executable file](https://github.com/mikeslattery/tunic/releases/latest/download/tunic.exe) from releases. +1. Download and run the +[latest executable file](https://github.com/mikeslattery/tunic/releases/latest/download/tunic.exe) +from releases. 1. Answer questions. 1. Let it run. It may take a long time. 1. Enjoy your new Linux OS! @@ -77,5 +83,6 @@ Distributed under the [GNU General Public License, version 3](https://www.gnu.or This software could inadvertantly and permanently destroy all data, leave a computer unbootable, or otherwise leave a computer in an undesirable state. This software comes as-is with absolutely no warranty. -Read sections [15, 16, and 17](https://www.gnu.org/licenses/gpl-3.0.html#section15) of the GNU GPL version 3 license for more information. +Read sections [15, 16, and 17](https://www.gnu.org/licenses/gpl-3.0.html#section15) +of the GNU GPL version 3 license for more information. diff --git a/build.ps1 b/build.ps1 index b214b84..b0f9409 100644 --- a/build.ps1 +++ b/build.ps1 @@ -8,87 +8,33 @@ # This is only for packaging a convenient, self-extracting .exe. # tunic.ps1 is usable without packaging. -# Install tools +# Strict mode Set-StrictMode -version 1.0 $ErrorActionPreference = 'Stop' -#mkdir -force "$env:TEMP" -$web = (New-Object System.Net.WebClient) +# Install tools -if( ! (get-installedmodule -name ps2exe -errorAction silentlyContinue) ) { - install-packageprovider -name nuget -force - Install-Module -force -confirm:$false ps2exe +if( ! ( Get-Command "choco" -ErrorAction SilentlyContinue ) ) { + $web = (New-Object System.Net.WebClient) + iex $web.DownloadString('https://chocolatey.org/install.ps1') } -if( ! ( Get-Command "7z" -ErrorAction SilentlyContinue ) ) { - if( ! ( Get-Command "choco" -ErrorAction SilentlyContinue ) ) { - iex $web.DownloadString('https://chocolatey.org/install.ps1') - } - choco install -y 7zip -} +if( ! ( Get-Command "makensis" -ErrorAction SilentlyContinue ) ) { + choco install -y nsis -if( ! ( test-path "$env:TEMP\7zSD.sfx" -errorAction SilentlyContinue) ) { - $web.downloadFile('https://www.7-zip.org/a/lzma1900.7z', "$env:TEMP\lzma.7z") - 7z e "$env:TEMP\lzma.7z" "-o$env:TEMP" bin\7zSD.sfx + new-alias -name makensis -value 'C:\Program Files (x86)\NSIS\makensis' -force } -#TODO: remove? -#$web = (New-Object System.Net.WebClient) -#iex $web.DownloadString('https://chocolatey.org/install.ps1') -#choco install -y nsis-advancedlogging -#$env:PATH += ";C:\Program Files (x86)\NSIS\Bin" - -function Test-Syntax -{ - [CmdletBinding(DefaultParameterSetName='File')] - param( - [Parameter(Mandatory=$true, ParameterSetName='File', Position = 0)] - [string]$Path, - - [Parameter(Mandatory=$true, ParameterSetName='String', Position = 0)] - [string]$Code - ) - - $Errors = @() - if($PSCmdlet.ParameterSetName -eq 'String'){ - [void][System.Management.Automation.Language.Parser]::` - ParseInput($Code,[ref]$null,[ref]$Errors) - } else { - [void][System.Management.Automation.Language.Parser]::` - ParseFile($Path,[ref]$null,[ref]$Errors) - } - - return [bool]($Errors.Count -lt 1) -} +# Syntax check -Test-Syntax 'tunic.ps1' +.\tunic.ps1 noop # Clean -Remove-Item "$env:TEMP\lzma.7z" -ErrorAction Ignore -Remove-Item tunic-script.exe -ErrorAction Ignore Remove-Item tunic.exe -ErrorAction Ignore -Remove-Item "$env:TEMP\tunic.7z" -ErrorAction Ignore -# Convert tunic.ps1 to tunic-script.exe - -invoke-ps2exe -inputfile tunic.ps1 -outputfile tunic-script.exe ` - -title Tunic ` - -credentialsGUI -requireAdmin ` - -noconsole -nooutput -noerror - -# Package self-extracting .exe - -7z a "$env:TEMP\tunic.7z" tunic.ps1 tunic-script.exe files\* - -gc -Encoding Byte -Path "$env:TEMP\7zSD.sfx","files\7z.conf","$env:TEMP\tunic.7z" ` - | sc -Encoding Byte tunic.exe - -copy tunic.exe ~\Desktop\tunic.exe - -# Clean +# Convert tunic.ps1 to tunic.exe -Remove-Item tunic-script.exe -ErrorAction Ignore -Remove-Item "$env:TEMP\tunic.7z" -ErrorAction Ignore +makensis tunic.nsi diff --git a/files/7z.conf b/files/7z.conf deleted file mode 100644 index cb333ca..0000000 --- a/files/7z.conf +++ /dev/null @@ -1,6 +0,0 @@ - ;!@Install@!UTF-8! -Title="Tunic Linux Installer" -ExecuteFile="C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -ExecuteParameters="-executionpolicy bypass -nologo -noninteractive -windowstyle hidden -file tunic.ps1" -Wait="yes" -;!@InstallEnd@! diff --git a/tunic.ps1 b/tunic.ps1 index 5c1e6c0..6432148 100644 --- a/tunic.ps1 +++ b/tunic.ps1 @@ -138,7 +138,7 @@ function ternary($expr, $ontrue, $onfalse) { function die($msg) { write-host $msg [System.Windows.Forms.Messagebox]::Show($msg) - exit 1 + $global:form.close() } function say($msg) { @@ -168,9 +168,9 @@ function checks() { } $osversion = [System.Environment]::OSVersion.version - if( $osversion.major -lt 6 -or ($osversion.major -eq 6 -and $osversion.minor -eq 0 ) ) { - # Windows 7 = 6.1 - die( 'Only Windows 7 or later supported' ) + if( $osversion.major -lt 10 ) { + # Windows 7=6.1, 8=6.2, 8.1=6.3 Windows 10=10 + die( 'Only Windows 10 supported' ) } if( [System.Environment]::Version.major -lt 3 ) { @@ -1122,6 +1122,25 @@ function gui() { return $form } +function hideConsole() { + + # .Net methods for hiding/showing the console in the background + Add-Type -Name Window -Namespace Console -MemberDefinition ' + [DllImport("Kernel32.dll")] + public static extern IntPtr GetConsoleWindow(); + + [DllImport("user32.dll")] + public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow); + ' + + $consoleWin = [Console.Window]::GetConsoleWindow() + + write-host "c = $consoleWin" + + # https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow + [Console.Window]::ShowWindow($consoleWin, 6) +} + # Installs full disk install. # Mainly for testing purposes. # User will have 'tunic' password. @@ -1181,6 +1200,11 @@ switch($op) { get-content -path 'preseed.tmp.cfg' rm 'preseed.tmp.cfg' } + {$_ -eq "hidden" } { + hideConsole + $global:form = (gui) + [void]$form.showDialog() + } default { $global:form = (gui) [void]$form.showDialog()