From 1f79b5a748e7dbc0d45154b810719e22f7408068 Mon Sep 17 00:00:00 2001 From: steve02081504 Date: Sat, 9 Dec 2023 15:51:38 +0800 Subject: [PATCH] Update --- .github/workflows/CI.yml | 3 + .github/workflows/runnerCI.yml | 25 +++++ opt/install | 2 +- opt/install.cmd | 2 +- opt/install.ps1 | 31 +++--- opt/run | 25 +++-- opt/run.cmd | 25 ++--- runner/.gitignore | 1 - runner/build.ps1 | 101 +++++++++++++++++++- runner/build/.gitignore | 3 + runner/build/desktop.ini | 2 + runner/main.ps1 | 27 ++++-- runner/tools/.gitignore | 4 + runner/tools/desktop.ini | 2 + src/commands/update.ps1 | 75 +++++++++------ src/fixers/VSCodeBackgroundJobsDisAbler.ps1 | 9 +- src/main.ps1 | 42 ++++++-- src/opt/install.ps1 | 98 +++++++++---------- src/system/BackgroundLoading.ps1 | 2 +- src/system/UI/loaded.ps1 | 7 +- src/system/UI/prompt/main.ps1 | 8 +- src/system/linux.ps1 | 5 + 22 files changed, 341 insertions(+), 158 deletions(-) create mode 100644 .github/workflows/runnerCI.yml delete mode 100644 runner/.gitignore create mode 100644 runner/build/.gitignore create mode 100644 runner/build/desktop.ini create mode 100644 runner/tools/.gitignore create mode 100644 runner/tools/desktop.ini diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index bfad957..559ae1f 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -2,6 +2,9 @@ name: CI on: push: + paths: + - 'src/**' + - 'opt/**' pull_request: branches: [ "master" ] workflow_dispatch: diff --git a/.github/workflows/runnerCI.yml b/.github/workflows/runnerCI.yml new file mode 100644 index 0000000..641a896 --- /dev/null +++ b/.github/workflows/runnerCI.yml @@ -0,0 +1,25 @@ +name: runner CI build + +on: + push: + paths: + - 'runner/**' + pull_request: + branches: [ "master" ] + workflow_dispatch: + +jobs: + test: + runs-on: windows-latest + steps: + - uses: actions/checkout@v3 + - name: Run a one-line script + shell : pwsh + run: | + ./runner/build.ps1 -OutputFile esh.exe + ./runner/build.ps1 -OutputFile esh-SigThief.exe -SigThief + - uses: actions/upload-artifact@v3 + with: + path: | + esh.exe + esh-SigThief.exe diff --git a/opt/install b/opt/install index f8c0b81..2e16671 100644 --- a/opt/install +++ b/opt/install @@ -2,5 +2,5 @@ SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) -pwsh -nologo -File "$SCRIPT_DIR/install.ps1" -FromScript "$@" +pwsh -nologo -File "$SCRIPT_DIR/install.ps1" "$@" exit $? diff --git a/opt/install.cmd b/opt/install.cmd index 5443163..bc0a9a1 100644 --- a/opt/install.cmd +++ b/opt/install.cmd @@ -1,2 +1,2 @@ -@pwsh -nologo -File "%~dp0\install.ps1" -FromScript %* +@pwsh -nologo -File "%~dp0\install.ps1" %* @exit /b %ERRORLEVEL% diff --git a/opt/install.ps1 b/opt/install.ps1 index e3cd1db..a02c3de 100644 --- a/opt/install.ps1 +++ b/opt/install.ps1 @@ -1,8 +1,8 @@ #!/usr/bin/env pwsh [CmdletBinding()]param( [switch]$Force=$false, - [ValidateSet('yes', 'no', 'ask', 'auto')][string]$StartEsh='auto', - [parameter(DontShow)][switch]$FromScript=$false + [switch]$Fix=$false, + [ValidateSet('yes', 'no', 'ask', 'auto')][string]$StartEsh='auto' ) function illusionlimb($path) { @@ -15,15 +15,24 @@ illusionlimb opt_init.ps1 if (-not $eshDir) { Remove-Item $env:LOCALAPPDATA/esh -Confirm -ErrorAction Ignore -Recurse - Remove-Item $env:TEMP/esh-master -Force -ErrorAction Ignore -Confirm:$false -Recurse - try { Invoke-WebRequest https://bit.ly/Esh-zip -OutFile $env:TEMP/Eshell.zip } - catch { - $Host.UI.WriteErrorLine("下载错误 终止脚本") - exit 1 + if (Get-Command git -ErrorAction Ignore) { + try { git clone https://github.com/steve02081504/esh $env:LOCALAPPDATA/esh --depth 1 } + catch { + $Host.UI.WriteErrorLine("下载错误 终止脚本") + exit 1 + } + } + else{ + Remove-Item $env:TEMP/esh-master -Force -ErrorAction Ignore -Confirm:$false -Recurse + try { Invoke-WebRequest https://bit.ly/Esh-zip -OutFile $env:TEMP/Eshell.zip } + catch { + $Host.UI.WriteErrorLine("下载错误 终止脚本") + exit 1 + } + Expand-Archive $env:TEMP/Eshell.zip $env:TEMP -Force + Remove-Item $env:TEMP/Eshell.zip -Force + Move-Item $env:TEMP/esh-master $env:LOCALAPPDATA/esh -Force } - Expand-Archive $env:TEMP/Eshell.zip $env:TEMP -Force - Remove-Item $env:TEMP/Eshell.zip -Force - Move-Item $env:TEMP/esh-master $env:LOCALAPPDATA/esh -Force $eshDir = "$env:LOCALAPPDATA/esh" try { Invoke-WebRequest 'https://bit.ly/SAO-lib' -OutFile "$eshDir/data/SAO-lib.txt" } catch { @@ -35,4 +44,4 @@ else { if ($EshellUI) { Write-Host "(并且你正在使用它 :))" } } -. $eshDir/src/opt/install.ps1 -Force:$Force -StartEsh:$StartEsh -FromScript:$FromScript +. $eshDir/src/opt/install.ps1 -Force:$Force -StartEsh:$StartEsh -Fix:$Fix diff --git a/opt/run b/opt/run index ad7be36..8336588 100644 --- a/opt/run +++ b/opt/run @@ -37,20 +37,17 @@ if [[ -d "/c/Windows" ]]; then SCRIPT_DIR=$(echo "$SCRIPT_DIR" | sed -e 's/\/c/C:/g' -e 's/\//\\/g' -e 's/^\\//g') fi -if [[ -z "$command" ]]; then - if [[ -z "$File" ]]; then - pwsh $parsed_args -nologo -NoExit -File "$SCRIPT_DIR/run.ps1" - else - File=$(echo "$File" | sed -e 's/"/`"/g') - pwsh $parsed_args -nologo -NoExit -Command ". $SCRIPT_DIR/run.ps1 ; . $File" - fi -else +pwshCommand="" +NoExit="-NoExit" +if [[ -n "$File" ]]; then + File=$(echo "$File" | sed -e 's/"/`"/g') + pwshCommand="$pwshCommand ; . $File" + NoExit="" +fi +if [[ -n "$command" ]]; then command=$(echo "$command" | sed -e 's/"/`"/g') - if [[ -z "$File" ]]; then - pwsh $parsed_args -nologo -Command ". $SCRIPT_DIR/run.ps1 ; Invoke-Expression $command" - else - File=$(echo "$File" | sed -e 's/"/`"/g') - pwsh $parsed_args -nologo -Command ". $SCRIPT_DIR/run.ps1 ; . $File ; Invoke-Expression $command" - fi + pwshCommand="$pwshCommand ; Invoke-Expression \"$command\"" + NoExit="" fi +pwsh $parsed_args -nologo $NoExit -command ". $SCRIPT_DIR/run.ps1$pwshCommand" exit $? diff --git a/opt/run.cmd b/opt/run.cmd index 921c106..4645624 100644 --- a/opt/run.cmd +++ b/opt/run.cmd @@ -26,26 +26,21 @@ for %%i in (%*) do ( ) ) -if defined command ( - set "command=!command:"=""!" -) +set "Noexit=-NoExit" +set "pwshCommand=" + if defined File ( set "File=!File:"=""!" + set "pwshCommand=!pwshCommand! ; . !File!" + set "Noexit=" ) - if defined command ( - if defined File ( - pwsh !remainingArgs! -nologo -Command ". %~dp0\run.ps1; . !File!; Invoke-Expression !command!" - ) else ( - pwsh !remainingArgs! -nologo -Command ". %~dp0\run.ps1; Invoke-Expression !command!" - ) -) else ( - if defined File ( - pwsh !remainingArgs! -nologo -Command ". %~dp0\run.ps1; . !File!" - ) else ( - pwsh !remainingArgs! -nologo -NoExit -File "%~dp0\run.ps1" - ) + set "command=!command:"=""!" + set "pwshCommand=!pwshCommand! ; Invoke-Expression !command!" + set "Noexit=" ) +pwsh.exe %remainingArgs% %Noexit% -nologo -Command ". %~dp0\run.ps1; !pwshCommand!" + @echo on @exit /b %ERRORLEVEL% diff --git a/runner/.gitignore b/runner/.gitignore deleted file mode 100644 index b0ad2a1..0000000 --- a/runner/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/esh.exe diff --git a/runner/build.ps1 b/runner/build.ps1 index 91defea..bb94be0 100644 --- a/runner/build.ps1 +++ b/runner/build.ps1 @@ -1,6 +1,99 @@ -[CmdletBinding()]param ($OutputFile = "$PSScriptRoot/esh.exe") +[CmdletBinding()] +param ( + $OutputFile = "$PWD/esh.exe", + [Parameter(ParameterSetName = 'SigThief')][switch]$SigThief = $false, + [switch]$DetailedLog = $false +) +DynamicParam { + if ($SigThief) { + $SigThiefParam = New-Object System.Management.Automation.RuntimeDefinedParameter('SigThiefFile', [string], ([System.Management.Automation.ParameterAttribute]@{HelpMessage = 'The file to steal signature from.' })) + $RuntimeParamDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary + $RuntimeParamDictionary.Add('SigThiefFile', $SigThiefParam) + return $RuntimeParamDictionary + } +} + +process { + function GetToolFromGit($ToolName, $ToolAuthor="steve02081504"){ + Write-Host "Downloading $ToolAuthor/$ToolName..." + try{ + if (Get-Command git -ErrorAction Ignore) { + git clone https://github.com/$ToolAuthor/$ToolName "$PSScriptRoot/tools/$ToolName" + } + else{ + Invoke-WebRequest -Uri https://github.com/$ToolAuthor/$ToolName/archive/refs/heads/master.zip -OutFile "$PSScriptRoot/tools/$ToolName.zip" + Expand-Archive -Path "$PSScriptRoot/tools/$ToolName.zip" -DestinationPath "$PSScriptRoot/tools" + Move-Item "$PSScriptRoot/tools/$ToolName-master" "$PSScriptRoot/tools/$ToolName" + Remove-Item "$PSScriptRoot/tools/$ToolName.zip" + } + } catch { + Write-Warning "Download failed." + Exit + } + Write-Host "Download complete." + } + if (-not (Test-Path "$PSScriptRoot/tools/ps2exe/ps2exe.ps1")) { + if(Get-Command ps2exe -ErrorAction Ignore){ + Write-Host "Existing ps2exe doesn't meet the functionality requirements needed for a build, downloading target fork..." + } + GetToolFromGit ps2exe + } + if (-not (Test-Path "$PSScriptRoot/tools/psminnifyer/psminnifyer.ps1")) { + GetToolFromGit psminnifyer + } + & $PSScriptRoot/tools/ps2exe/ps2exe.ps1 $PSScriptRoot/main.ps1 "$PSScriptRoot/build/esh.exe" -NoConsole ` + -Minifyer { $_ | &$PSScriptRoot/tools/psminnifyer/psminnifyer.ps1 } ` + -TempDir "$PSScriptRoot/build" -iconFile $PSScriptRoot/../img/esh.ico ` + -title 'E-Shell' -description 'E-Shell' -version '1960.7.17.13' ` + -company 'E-tek' -product 'E-Sh' -copyright '(c) E-tek Corporation. All rights reserved.' | Out-Default + + $ConfuserFile = if (Test-Path "$PSScriptRoot/tools/ConfuserEx/Confuser.CLI.exe") { "$PSScriptRoot/tools/ConfuserEx/Confuser.CLI.exe" } + else { (Get-Command Confuser.CLI -ErrorAction Ignore).Source } + if(-not $ConfuserFile){ + Write-Host "Confuser.CLI not found. Downloading..." + try{ + Invoke-WebRequest https://github.com/mkaring/ConfuserEx/releases/latest/download/ConfuserEx-CLI.zip -OutFile $PSScriptRoot/tools/ConfuserEx.zip + New-Item -ItemType Directory -Force -Path $PSScriptRoot/tools/ConfuserEx | Out-Null + Expand-Archive -Path $PSScriptRoot/tools/ConfuserEx.zip -DestinationPath $PSScriptRoot/tools/ConfuserEx + } catch { + Write-Warning "Download failed.. Skipping obfuscation. +Download it from https://github.com/mkaring/ConfuserEx +and put it in the environment path or in $PSScriptRoot/tools/ConfuserEx" + } + if (Test-Path "$PSScriptRoot/tools/ConfuserEx/Confuser.CLI.exe") { + $ConfuserFile = "$PSScriptRoot/tools/ConfuserEx/Confuser.CLI.exe" + Write-Host "Download complete." + } + } + if($ConfuserFile){ + $OutputLength = (Get-Item "$PSScriptRoot/build/esh.exe").Length + & $ConfuserFile -n -o="$PSScriptRoot/build" "$PSScriptRoot/build/esh.exe" | Out-Null #太长了 + $ObfusLength = (Get-Item "$PSScriptRoot/build/esh.exe").Length + if($ObfusLength -ne $OutputLength){ + Write-Host "Obfuscation complete -> $ObfusLength bytes" + } + elseif($LASTEXITCODE -eq 1){ + Write-Warning "Obfuscation failed." + } + } -if (-not (Get-Module -ListAvailable ps2exe)) { - Install-Module ps2exe + if ($SigThief) { + if (-not (Test-Path "$PSScriptRoot/tools/SigThief/sigthief.py")) { + GetToolFromGit SigThief + } + if (-not $SigThiefFile) { + $SigThiefFile = "$env:windir\explorer.exe" + } + if (Get-Command python -ErrorAction Ignore) { + python "$PSScriptRoot/tools/SigThief/sigthief.py" -i $SigThiefFile -t "$PSScriptRoot/build/esh.exe" -o $OutputFile + } + else { + Write-Warning "Python not found. Skipping sigthief." + Copy-Item "$PSScriptRoot/build/esh.exe" $OutputFile + } + } + else{ + Copy-Item "$PSScriptRoot/build/esh.exe" $OutputFile + Write-Host "Skipping sigature theft." + } } -Invoke-ps2exe $PSScriptRoot/main.ps1 $OutputFile -NoConsole -iconFile $PSScriptRoot/../img/esh.ico -title 'E-Shell' -description 'E-Shell' -version '1960.7.17.13' -company 'E-tek' -product 'E-Sh' -copyright '(c) E-tek Corporation. All rights reserved.' diff --git a/runner/build/.gitignore b/runner/build/.gitignore new file mode 100644 index 0000000..cbfa331 --- /dev/null +++ b/runner/build/.gitignore @@ -0,0 +1,3 @@ +/esh.exe +/esh.pdb +/main.ps1 diff --git a/runner/build/desktop.ini b/runner/build/desktop.ini new file mode 100644 index 0000000..d2d1ad9 --- /dev/null +++ b/runner/build/desktop.ini @@ -0,0 +1,2 @@ +[.ShellClassInfo] +IconResource=C:\WINDOWS\System32\SHELL32.dll,261 diff --git a/runner/main.ps1 b/runner/main.ps1 index e279c94..1efdead 100644 --- a/runner/main.ps1 +++ b/runner/main.ps1 @@ -19,15 +19,24 @@ if (-not $eshDir) { if (-not $eshDir) { Remove-Item $env:LOCALAPPDATA/esh -Confirm -ErrorAction Ignore -Recurse - Remove-Item $env:TEMP/esh-master -Force -ErrorAction Ignore -Confirm:$false -Recurse - try { Invoke-WebRequest https://bit.ly/Esh-zip -OutFile $env:TEMP/Eshell.zip } - catch { - $Host.UI.WriteErrorLine("下载错误 终止程序") - exit 1 + if (Get-Command git -ErrorAction Ignore) { + try { git clone https://github.com/steve02081504/esh $env:LOCALAPPDATA/esh --depth 1 } + catch { + $Host.UI.WriteErrorLine("下载错误 终止程序") + exit 1 + } + } + else{ + Remove-Item $env:TEMP/esh-master -Force -ErrorAction Ignore -Confirm:$false -Recurse + try { Invoke-WebRequest https://bit.ly/Esh-zip -OutFile $env:TEMP/Eshell.zip } + catch { + $Host.UI.WriteErrorLine("下载错误 终止程序") + exit 1 + } + Expand-Archive $env:TEMP/Eshell.zip $env:TEMP -Force + Remove-Item $env:TEMP/Eshell.zip -Force + Move-Item $env:TEMP/esh-master $env:LOCALAPPDATA/esh -Force } - Expand-Archive $env:TEMP/Eshell.zip $env:TEMP -Force - Remove-Item $env:TEMP/Eshell.zip -Force - Move-Item $env:TEMP/esh-master $env:LOCALAPPDATA/esh -Force $eshDir = "$env:LOCALAPPDATA/esh" try { Invoke-WebRequest 'https://bit.ly/SAO-lib' -OutFile "$eshDir/data/SAO-lib.txt" } catch { @@ -36,7 +45,7 @@ if (-not $eshDir) { } if ($RunInstall){ - . $eshDir/src/opt/install.ps1 $RemainingArguments + Invoke-Expression "&$eshDir/src/opt/install.ps1 $RemainingArguments" exit } if (-not (Get-Command pwsh -ErrorAction Ignore)) { diff --git a/runner/tools/.gitignore b/runner/tools/.gitignore new file mode 100644 index 0000000..4adc05a --- /dev/null +++ b/runner/tools/.gitignore @@ -0,0 +1,4 @@ +/PS2EXE +/psminnifyer +/SigThief +/ConfuserEx diff --git a/runner/tools/desktop.ini b/runner/tools/desktop.ini new file mode 100644 index 0000000..a981eb6 --- /dev/null +++ b/runner/tools/desktop.ini @@ -0,0 +1,2 @@ +[.ShellClassInfo] +IconResource=C:\WINDOWS\System32\SHELL32.dll,71 diff --git a/src/commands/update.ps1 b/src/commands/update.ps1 index a5a5048..0645ee0 100644 --- a/src/commands/update.ps1 +++ b/src/commands/update.ps1 @@ -1,13 +1,13 @@ function global:Update-SAO-lib { - $espath = $EshellUI.Sources.Path - # 如果"$espath/data/SAO-lib.txt"是链接 - if ((Get-Item "$espath/data/SAO-lib.txt").Attributes -match 'ReparsePoint') { + $eshDir = $EshellUI.Sources.Path + # 如果"$eshDir/data/SAO-lib.txt"是链接 + if ((Get-Item "$eshDir/data/SAO-lib.txt").Attributes -match 'ReparsePoint') { Write-Information "SAO-lib.txt is a link, Skip updating" return } try { #下载最新的SAO-lib - Invoke-WebRequest 'https://github.com/steve02081504/SAO-lib/raw/master/SAO-lib.txt' -OutFile "$espath/data/SAO-lib.txt" + Invoke-WebRequest 'https://github.com/steve02081504/SAO-lib/raw/master/SAO-lib.txt' -OutFile "$eshDir/data/SAO-lib.txt" } catch {} } @@ -17,42 +17,57 @@ function global:Update-gcc-Kawaii { Write-Information "the original gcc.mo file is now backed up to gcc.mo.bak" mv /usr/share/locale/zh_CN/LC_MESSAGES/gcc.mo /usr/share/locale/zh_CN/LC_MESSAGES/gcc.mo.bak } - $espath = $EshellUI.Sources.Path - Invoke-WebRequest 'https://github.com/Bill-Haku/kawaii-gcc/raw/main/gcc-zh.po' -OutFile "$espath/data/gcc-zh.po" - msgfmt "$espath/data/gcc-zh.po" -o /usr/share/locale/zh_CN/LC_MESSAGES/gcc.mo - Remove-Item "$espath/data/gcc-zh.po" -Force + $eshDir = $EshellUI.Sources.Path + Invoke-WebRequest 'https://github.com/Bill-Haku/kawaii-gcc/raw/main/gcc-zh.po' -OutFile "$eshDir/data/gcc-zh.po" + msgfmt "$eshDir/data/gcc-zh.po" -o /usr/share/locale/zh_CN/LC_MESSAGES/gcc.mo + Remove-Item "$eshDir/data/gcc-zh.po" -Force gcc } function global:Update-EShell { Update-SAO-lib - $espath = $EshellUI.Sources.Path - # 如果"$espath"是git仓库 - if (Test-Path "$espath/.git/config") { + $eshDir = $EshellUI.Sources.Path + # 如果"$eshDir"是git仓库 + if (Test-Path "$eshDir/.git/config") { $pathNow = $PWD - Set-Location $espath + Set-Location $eshDir git pull --rebase Set-Location $pathNow - reload - return } - $praentpath = Split-Path $espath - $datapath = "$espath/data" - try { - #下载最新的EShell - Invoke-WebRequest 'https://github.com/steve02081504/esh/archive/refs/heads/master.zip' -OutFile "$datapath/master.zip" - #删除除了data和desktop.ini文件夹以外的所有文件 - Get-ChildItem "$espath" -Force | Where-Object { $_.Name -notin @('data', 'desktop.ini') } | Remove-Item -Recurse -Force - #更新文件 - Rename-Item "$espath" "$praentpath/esh-master" - Expand-Archive "$praentpath/esh-master/data/master.zip" "$praentpath" -Force - Rename-Item "$praentpath/esh-master" "$espath" - #删除压缩包 - Remove-Item "$datapath/master.zip" -Force - #重载EShell - reload + else{ + $praentpath = Split-Path $eshDir + $datapath = "$eshDir/data" + try { + if (Test-Command git){ + # 升级到git仓库 + git clone https://github.com/steve02081504/esh $datapath/esh --depth 1 --no-checkout + #移动并覆盖文件 + Move-Item "$datapath/esh/.git" $eshDir -Force + Remove-Item "$datapath/esh" -Force -Recurse + #恢复文件 + $pathNow = $PWD + Set-Location $eshDir + git reset --hard HEAD + Set-Location $pathNow + } + else{ + #下载最新的EShell + Invoke-WebRequest 'https://github.com/steve02081504/esh/archive/refs/heads/master.zip' -OutFile "$datapath/master.zip" + #删除除了data和desktop.ini文件夹以外的所有文件 + Get-ChildItem "$eshDir" -Force | Where-Object { $_.Name -notin @('data', 'desktop.ini') } | Remove-Item -Recurse -Force + #更新文件 + Rename-Item "$eshDir" "$praentpath/esh-master" + Expand-Archive "$praentpath/esh-master/data/master.zip" "$praentpath" -Force + #删除压缩包 + Remove-Item "$datapath/master.zip" -Force + Rename-Item "$praentpath/esh-master" "$eshDir" + } + } + catch {} } - catch {} + $eshDirFromEnv = $EshellUI.Im.InEnvPath() + . $eshDir/src/opt/install.ps1 -Fix + reload } function global:Update-All-Paks { diff --git a/src/fixers/VSCodeBackgroundJobsDisAbler.ps1 b/src/fixers/VSCodeBackgroundJobsDisAbler.ps1 index ecfc0f0..4913ff5 100644 --- a/src/fixers/VSCodeBackgroundJobsDisAbler.ps1 +++ b/src/fixers/VSCodeBackgroundJobsDisAbler.ps1 @@ -1,14 +1,13 @@ if ($EshellUI.Im.VSCodeExtension -and ($host.Version -le [version]'2023.8.0')) { - $EshellUI.BackgroundJobs | ForEach-Object { & $_ } - $EshellUI.BackgroundJobs.Clear() - Unregister-Event -SubscriptionId $EshellUI.RegisteredEvents.IdleEvent.RawData.SubscriptionId -Force - $EshellUI.RegisteredEvents.Remove('IdleEvent') + $EshellUI.BackgroundJobs.Wait() + Unregister-Event -SubscriptionId $EshellUI.RegisteredEvents.BackgroundJobs.RawData.SubscriptionId -Force + $EshellUI.RegisteredEvents.Remove('BackgroundJobs') $EshellUI.LoadingLog.AddWarning( "EshellUI's BackgroundJobs has been disabled due to a bug of PowerShell VSCode Extension. See $( $VirtualTerminal.Styles.Underline+$VirtualTerminal.Colors.BrightCyan )https://github.com/PowerShell/vscode-powershell/issues/4851$( - $VirtualTerminal.Styles.NoUnderline+$VirtualTerminal.Colors[(Get-Host).PrivateData.WarningForegroundColor.ToString()] + $VirtualTerminal.Styles.NoUnderline+$VirtualTerminal.Colors[${Out-Performance}.Warning.Color] ) for more info." ) } diff --git a/src/main.ps1 b/src/main.ps1 index 875c3b2..9df91fa 100644 --- a/src/main.ps1 +++ b/src/main.ps1 @@ -22,7 +22,7 @@ $EshellUI = ValueEx @{ param($Path=$env:Path) $result = $false $Path.Split(";") | ForEach-Object { - if ($_ -like "$([regex]::Escape($this.Sources.Path))[\\/]path*") { + if ($_ -match "$([regex]::Escape($this.Sources.Path))[\\/]path*") { $result = $true } } @@ -100,6 +100,13 @@ $EshellUI = ValueEx @{ & $this.Pop() $ProgressPreference = $OriginalPref } + 'method:Push' = { + param($Jobs) + $Jobs | ForEach-Object { $this.Add($_) } | Out-Null + } + 'method:Wait' = { + while($this.Count) { $this.PopAndRun() } + } } OtherData = @{ ReloadSafeVariables = $EshellUI.OtherData.ReloadSafeVariables ?? @{} @@ -130,6 +137,7 @@ $EshellUI = ValueEx @{ $this.State.VariablesLoaded = $true } 'method:Start' = { + param ($Arguments) if ($this.State.Started) { Write-Error 'esh is already started.' return @@ -145,11 +153,11 @@ $EshellUI = ValueEx @{ EnterHandler = (Get-PSReadLineKeyHandler Enter).Function } $this.RegisteredEvents=@{ - ExitingEvent = @{ + SaveVariables = @{ ID = 'PowerShell.Exiting' Action = {$EshellUI.SaveVariables()} } - IdleEvent = @{ + BackgroundJobs = @{ ID = 'PowerShell.OnIdle' Action = { if ($EshellUI.BackgroundJobs.Count) { @@ -158,6 +166,9 @@ $EshellUI = ValueEx @{ } } } + if($Arguments.NoVariableSaving){ + $this.RegisteredEvents.Remove('SaveVariables') + } $this.RegisteredEvents.GetEnumerator() | ForEach-Object { $_ = $_.Value Register-EngineEvent $_.ID -SupportEvent -Action $_.Action @@ -176,10 +187,20 @@ $EshellUI = ValueEx @{ . $PSScriptRoot/system/UI/prompt/main.ps1 . $PSScriptRoot/system/BackgroundLoading.ps1 + if (-not $Arguments.NoProfile) { + $EshellUI.BackgroundJobs.Push({ + if (Test-Path ~/.esh_rc.ps1) { + . ~/.esh_rc.ps1 + } + }) + } + if ($Arguments.NoBackgroundLoading) { + $EshellUI.BackgroundJobs.Wait() + } Get-ChildItem "$PSScriptRoot/commands" *.ps1 | ForEach-Object { . $_.FullName } Get-ChildItem "$PSScriptRoot/Fixers" *.ps1 | ForEach-Object { . $_.FullName } - . $PSScriptRoot/system/UI/loaded.ps1 + . $PSScriptRoot/system/UI/loaded.ps1 -Arguments $Arguments $this.State.Started = $true $this.OtherData.AfterEshLoaded = @{ @@ -275,12 +296,14 @@ $EshellUI = ValueEx @{ if (-not $NotEnterNestedPrompt) { $NestedPromptLevel-- } } 'method:RunFromScript' = { - param($Invocation) + param($Invocation, $Arguments) try { if (-not $this.State.Started) { $this.Init($Invocation) - $this.LoadVariables() - $this.Start() + if(-not $Arguments.NoVariableLoading) { + $this.LoadVariables() + } + $this.Start($Arguments) $StartedInThisCall = $true } $global:EshellUI ??= $this @@ -299,7 +322,7 @@ $EshellUI = ValueEx @{ } } 'method:CompileExeFile' = { - param($OutputFile) + param($OutputFile=$PWD.Path) if(IsLinuxPath $OutputFile){ $OutputFile = LinuxPathToWindowsPath $OutputFile } @@ -313,6 +336,7 @@ $EshellUI = ValueEx @{ return } } - . "$($this.Sources.Path)/runner/build.ps1" -OutputFile $OutputFile | Out-Null + . "$($this.Sources.Path)/runner/build.ps1" -OutputFile $OutputFile + "Compiled to $(AutoShortPath $OutputFile) with size $((Get-Item $OutputFile).Length) bytes" } } diff --git a/src/opt/install.ps1 b/src/opt/install.ps1 index d434f85..c1f7dd5 100644 --- a/src/opt/install.ps1 +++ b/src/opt/install.ps1 @@ -1,8 +1,8 @@ using namespace System.Management.Automation.Host param( [switch]$Force=$false, - [ValidateSet('yes', 'no', 'ask', 'auto')][string]$StartEsh='auto', - [parameter(DontShow)][switch]$FromScript=$false + [switch]$Fix=$false, + [ValidateSet('yes', 'no', 'ask', 'auto')][string]$StartEsh='auto' ) . $PSScriptRoot/base.ps1 @@ -45,55 +45,60 @@ if ($IsWindows) { } } } -if ((-not $eshDirFromEnv) -and (YorN "要安装 Esh 到环境变量吗?" -helpMessageY "将可以在任何地方使用``esh``或``EShell``命令" -SkipAsDefault:$Force)) { - $env:Path += "`;$eshDir/path" - $UserPath = [Environment]::GetEnvironmentVariable("Path", "User") + "`;$eshDir/path" - [Environment]::SetEnvironmentVariable("Path", $UserPath, "User") - Write-Host "安装成功!`n现在可以在任何地方使用 ``esh`` 或 ``EShell`` 命令了。" - $eshDirFromEnv = $true -} -if ($PSVersionTable.PSVersion.Major -lt 6) { - Write-Warning "当前版本的 PowerShell 不支持 Esh 作为配置文件,跳过配置文件的添加部分`n你可以通过使用合适的``pwsh``重新运行该脚本来添加配置文件" -} -else { - $profilesDir = Split-Path $PROFILE - $startScript = ". $eshDir/opt/run.ps1" - $universalProfile = "$profilesDir/profile.ps1" - function checkLoaded ($theProfile) { (Get-Content $theProfile -ErrorAction Ignore) -contains $startScript } - $added = $false - @( - $universalProfile - $profile - ) | ForEach-Object { - if (checkLoaded $_) { - Write-Information "在${_}中已经加载过esh" - $added = $true - } +if (-not $Fix){ + if ((-not $eshDirFromEnv) -and (YorN "要安装 Esh 到环境变量吗?" -helpMessageY "将可以在任何地方使用``esh``或``EShell``命令" -SkipAsDefault:$Force)) { + $env:Path += "`;$eshDir/path" + $UserPath = [Environment]::GetEnvironmentVariable("Path", "User") + "`;$eshDir/path" + [Environment]::SetEnvironmentVariable("Path", $UserPath, "User") + Write-Host "安装成功!`n现在可以在任何地方使用 ``esh`` 或 ``EShell`` 命令了。" + $eshDirFromEnv = $true + } + if ($Host.Name -eq 'PSEXE') { + Write-Warning "通过exe安装会跳过配置文件的设置(毕竟这不是任何powershell环境)`n你随时可以通过使用合适的``pwsh``运行$eshDir/opt/install来添加配置文件" } - if ((-not $added) -and (YorN "要添加 Eshell 到 PowerShell 配置文件吗?" -defaultN:($Host.Name -ne 'Visual Studio Code Host') -helpMessageY "powershell将表现得与Esh相同" -helpMessageN "让powershell保持原样,你仍然可以通过``esh``命令来使用Esh(推荐)" -SkipAsDefault:$Force)) { + elseif ($PSVersionTable.PSVersion.Major -lt 6) { + Write-Warning "当前版本的 PowerShell 不支持 Esh 作为配置文件,跳过配置文件的添加部分`n你可以通过使用合适的``pwsh``重新运行该脚本来添加配置文件" + } + else { + $profilesDir = Split-Path $PROFILE + $startScript = ". $eshDir/opt/run.ps1" + $universalProfile = "$profilesDir/profile.ps1" + function checkLoaded ($theProfile) { (Get-Content $theProfile -ErrorAction Ignore) -contains $startScript } + $added = $false @( $universalProfile $profile ) | ForEach-Object { - if (Test-Path $_) { - Write-Information "在${_}中添加了esh加载语句" - Add-Content $_ $startScript + if (checkLoaded $_) { + Write-Information "在${_}中已经加载过esh" $added = $true } } - if (-not $added) { - if(-not $Force){ - do { - $response = $Host.UI.PromptForChoice("未找到可用的profile文件", "选择你想要新建并添加Esh加载的配置文件", @( - [ChoiceDescription]::new("&0`b当前应用针对性配置文件", $profile), - [ChoiceDescription]::new("&1`b通用配置文件", $universalProfile) - ), 0) - } until ($response -ne -1) + if ((-not $added) -and (YorN "要添加 Eshell 到 PowerShell 配置文件吗?" -defaultN:($Host.Name -ne 'Visual Studio Code Host') -helpMessageY "powershell将表现得与Esh相同" -helpMessageN "让powershell保持原样,你仍然可以通过``esh``命令来使用Esh(推荐)" -SkipAsDefault:$Force)) { + @( + $universalProfile + $profile + ) | ForEach-Object { + if (Test-Path $_) { + Write-Information "在${_}中添加了esh加载语句" + Add-Content $_ $startScript + $added = $true + } + } + if (-not $added) { + if(-not $Force){ + do { + $response = $Host.UI.PromptForChoice("未找到可用的profile文件", "选择你想要新建并添加Esh加载的配置文件", @( + [ChoiceDescription]::new("&0`b当前应用针对性配置文件", $profile), + [ChoiceDescription]::new("&1`b通用配置文件", $universalProfile) + ), 0) + } until ($response -ne -1) + } + $theProfile = @($universalProfile, $profile)[$response] + New-Item -ItemType Directory -Force -Path $profilesDir | Out-Null + Write-Information "在${theProfile}中添加了esh加载语句" + Set-Content $theProfile $startScript } - $theProfile = @($universalProfile, $profile)[$response] - New-Item -ItemType Directory -Force -Path $profilesDir | Out-Null - Write-Information "在${theProfile}中添加了esh加载语句" - Set-Content $theProfile $startScript } } } @@ -141,16 +146,13 @@ if (-not (Get-Command pwsh -ErrorAction Ignore)) { $Host.UI.WriteErrorLine("esh的运行需要PowerShell 6或以上`n访问 https://aka.ms/pscore6 来获取PowerShell 6+ 并使得``pwsh``命令在环境中可用以使得esh能够正常工作") } else{ - $StartEsh = (-not $EshellUI) -and $(switch ($StartEsh) { + [bool]$StartEsh = (-not $EshellUI) -and $(switch ($StartEsh) { no { $false } yes { $true } default { YorN "要使用 Eshell 吗?" -SkipAsDefault:($Force -and $StartEsh -eq 'auto') } }) } if ($StartEsh) { - if ($FromScript -or ($PSVersionTable.PSVersion.Major -lt 6)) { - . $eshDir/opt/run - [System.Environment]::Exit($LastExitCode) - } - else { . $eshDir/opt/run.ps1 -Invocation $MyInvocation } + . $eshDir/opt/run + [System.Environment]::Exit($LastExitCode) } diff --git a/src/system/BackgroundLoading.ps1 b/src/system/BackgroundLoading.ps1 index 327ae9c..e4cca3d 100644 --- a/src/system/BackgroundLoading.ps1 +++ b/src/system/BackgroundLoading.ps1 @@ -1,4 +1,4 @@ -$EshellUI.BackgroundJobs.AddRange(@( +$EshellUI.BackgroundJobs.Push(@( { Update-FormatData -PrependPath "$($EshellUI.Sources.Path)/data/formatxml/ls.bare.format.ps1xml" if ($Host.UI.SupportsVirtualTerminal) { diff --git a/src/system/UI/loaded.ps1 b/src/system/UI/loaded.ps1 index f705e38..0560586 100644 --- a/src/system/UI/loaded.ps1 +++ b/src/system/UI/loaded.ps1 @@ -1,3 +1,4 @@ +param ($Arguments) if ($error.Count -eq $EshellUI.OtherData.BeforeEshLoaded.Errors.Count) { $CursorPos = $host.UI.RawUI.CursorPosition $CursorPos.Y -= 3 @@ -6,8 +7,10 @@ if ($error.Count -eq $EshellUI.OtherData.BeforeEshLoaded.Errors.Count) { } . $PSScriptRoot/logo.ps1 -$EshellUI.Logo.Print() -if($EshellUI.LoadingLog.Count) { +if(-not $Arguments.NoLogo) { + $EshellUI.Logo.Print() +} +if($EshellUI.LoadingLog.Count -and -not $Arguments.NoLoadingLog) { $EshellUI.LoadingLog.Print() Write-Host } diff --git a/src/system/UI/prompt/main.ps1 b/src/system/UI/prompt/main.ps1 index 218823d..7a47f75 100644 --- a/src/system/UI/prompt/main.ps1 +++ b/src/system/UI/prompt/main.ps1 @@ -1,5 +1,4 @@ $EshellUI.Prompt = ValueEx @{ - Parent = $EshellUI Builders = [ordered]@{} BuildMethods = ValueEx @{ 'method:BaseNewlineCheck' = { @@ -23,13 +22,8 @@ $EshellUI.Prompt = ValueEx @{ # 关于0.42和0.66的解释:0.66+0.42=1.08,这象征着108好汉于三国起义 杀死了汉朝的最后一位皇帝,从而结束了原神 } 'method:Get' = { - $local:EshellUI = $this.Parent - $path_str = $PWD.Path - if ($path_str.StartsWith($HOME) -or $path_str.StartsWith($EshellUI.MSYS.RootPath)) { - $path_str = WindowsPathToLinuxPath $path_str - } $this.LastBuild=@{ - Tokens=@($VirtualTerminal.Colors.Reset+$path_str) + Tokens=@($VirtualTerminal.Colors.Reset+(AutoShortPath $PWD.Path)) BuilderOutput=@{} } $this.Builders.GetEnumerator() | ForEach-Object { diff --git a/src/system/linux.ps1 b/src/system/linux.ps1 index 05b0c49..9e0c870 100644 --- a/src/system/linux.ps1 +++ b/src/system/linux.ps1 @@ -107,6 +107,11 @@ function global:WindowsPathToLinuxPath($Path) { $Path = $Path.Replace("\", "/") return $Path } +function global:AutoShortPath($Path) { + if ($Path.StartsWith($HOME) -or $Path.StartsWith($EshellUI.MSYS.RootPath)) { + WindowsPathToLinuxPath $Path + } +} if (Test-Command rm.exe) { . "$($EshellUI.Sources.Path)/src/commands/special/linux_bins.ps1"