function Start-Demo { param($file=".\demo.txt", [int]$command=0) $CommentColor = "Yellow" $MetaCommandColor = "Red" Clear-Host #Typo fun $bs = [char]8 $_Random = New-Object System.Random $_lines = @(Get-Content $file) $_starttime = [DateTime]::now Write-Host -for $CommentColor "" # We use a FOR and an INDEX ($_i) instead of a FOREACH because # it is possible to start at a different location and/or jump # around in the order. for ($_i = $Command; $_i -lt $_lines.count; $_i++) { if ($_lines[$_i].StartsWith("#")) { Write-Host -NoNewLine $("`n[$_i]PS> ") Write-Host -NoNewLine -Foreground $CommentColor $($($_Lines[$_i]) + " ") continue }else { Write-Host -NoNewLine $("`n[$_i]PS> ") $_SimulatedLine = $($_Lines[$_i]) + " " for ($_j = 0; $_j -lt $_SimulatedLine.Length; $_j++) { Write-Host -NoNewLine $_SimulatedLine[$_j] if ($_Backup -eq $false) { #typo fun if ($_Random.Next(50) -le 1) { $rchar = [char]($_Random.Next(90) + 32) Start-Sleep -milliseconds $(10 + $_Random.Next(100)) Write-Host -NoNewLine $rchar Start-Sleep -milliseconds $(10 + $_Random.Next(100)) Write-Host -NoNewLine $bs } Start-Sleep -milliseconds $(10 + $_Random.Next(30)) } } $_Backup = $false } # Put the current command in the Window Title along with the demo duration $_Duration = [DateTime]::Now - $_StartTime $Host.UI.RawUI.WindowTitle = "[{0}m, {1}s] {2}" -f [int]$_Duration.TotalMinutes, [int]$_Duration.Seconds, $($_Lines[$_i]) $_OldColor = $host.UI.RawUI.ForeGroundColor $host.UI.RawUI.ForeGroundColor = $MetaCommandColor $_input=[System.Console]::ReadLine() $host.UI.RawUI.ForeGroundColor = $_OldColor switch ($_input) { "?" { Write-Host -ForeGroundColor $CommentColor "Running demo: $file`n(q) Quit (!) Suspend (#x) Goto Command #x (fx) Find cmds using X`n(B) backup (t) Timecheck (s) Skip (d) Dump demo" $_i -= 1 } "b" { if($_i -gt 0) { $_i -- while (($_i -gt 0) -and ($_lines[$($_i)].StartsWith("#"))) { $_i -= 1 } } $_i -- $_Backup = $true } "q" { Write-Host -ForeGroundColor $CommentColor "" return } "s" { Write-Host -ForeGroundColor $CommentColor "" } "d" { for ($_ni = 0; $_ni -lt $_lines.Count; $_ni++) { if ($_i -eq $_ni) { Write-Host -ForeGroundColor $MetaCommandColor ("*" * 80) } Write-Host -ForeGroundColor $CommentColor ("[{0,2}] {1}" -f $_ni, $_lines[$_ni]) } $_i -= 1 } "t" { $_Duration = [DateTime]::Now - $_StartTime Write-Host -ForeGroundColor $CommentColor $("Demo has run {0} Minutes and {1} Seconds" -f [int]$_Duration.TotalMinutes, [int]$_Duration.Seconds) $_i -= 1 } {$_.StartsWith("f")} { for ($_ni = 0; $_ni -lt $_lines.Count; $_ni++) { if ($_lines[$_ni] -match $_.SubString(1)) { Write-Host -ForeGroundColor $CommentColor ("[{0,2}] {1}" -f $_ni, $_lines[$_ni]) } } $_i -= 1 } {$_.StartsWith("!")} { if ($_.Length -eq 1) { Write-Host -ForeGroundColor $CommentColor "" function Prompt {"[Demo Suspended]`nPS>"} $host.EnterNestedPrompt() }else { trap [System.Exception] {Write-Error $_;continue;} Invoke-Expression $(".{" + $_.SubString(1) + "}| out-host") } $_i -= 1 } {$_.StartsWith("#")} { $_i = [int]($_.SubString(1)) - 1 continue } default { trap [System.Exception] {Write-Error $_;continue;} Invoke-Expression $(".{" + $_lines[$_i] + "}| out-host") $_Duration = [DateTime]::Now - $_StartTime $Host.UI.RawUI.WindowTitle = "[{0}m, {1}s] {2}" -f [int]$_Duration.TotalMinutes, [int]$_Duration.Seconds, $($_Lines[$_i]) [System.Console]::ReadLine() } } } $_Duration = [DateTime]::Now - $_StartTime Write-Host -ForeGroundColor $CommentColor $("" -f [int]$_Duration.TotalMinutes, [int]$_Duration.Seconds) Write-Host -ForeGroundColor $CommentColor $([DateTime]::now) }