src/ReadScriptFile.ps1
function ReadScriptFile($File) { $Content = if ($File -match "^(https?|ftp)://") { (Invoke-WebRequest -Uri $File -ErrorAction SilentlyContinue).Content } else { Get-Content -LiteralPath $File -Encoding UTF8 -ErrorAction SilentlyContinue -Raw } Write-Host "Reading file $([System.IO.Path]::GetFileName($File)) size $($Content.Length) bytes" $Content = $Content -join "`n" -split '\r?\n' if (-not $Content) { Write-Error "No data found. May be read error or file protected." return } Write-Verbose "Done reading file $([System.IO.Path]::GetFileName($File)), starting preprocess..." Preprocessor $Content $File Write-Verbose "Done preprocess file $([System.IO.Path]::GetFileName($File))" } function Preprocessor($Content, $FilePath) { $Result = @() # 处理#_if <PSEXE/PSScript>、#_else、#_endif for ($index = 0; $index -lt $Content.Count; $index++) { $Line = $Content[$index] if ($Line -match "^\s*#_if\s+(?<condition>\S+)\s*(?!#.*)") { $condition = $Matches["condition"] $condition = switch ($condition) { 'PSEXE' { $TRUE } 'PSScript' { $False } default { Write-Error "Unknown condition: $condition`nassuming false."; $False } } while ($index -lt $Content.Count) { $index++ $Line = $Content[$index] if ($Line -match "^\s*#_else\s*(?!#.*)") { $condition = -not $condition } if ($Line -match "^\s*#_endif\s*(?!#.*)") { break } if ($condition) { $Result += $Line } } if ($Line -notmatch "^\s*#_endif\s*(?!#.*)") { Write-Error "Missing #_endif" return } } else { $Result += $Line } } $ScriptRoot = $FilePath.Substring(0, $FilePath.LastIndexOfAny(@('\', '/'))) function GetIncludeFilePath($rest) { if ($rest -match "((\'[^\']*\')+)\s*(?!#.*)") { $file = $Matches[1] $file = $file.Substring(1, $file.Length - 2).Replace("''", "'") } elseif ($rest -match '((\"[^\"]*\")+)\s*(?!#.*)') { $file = $Matches[1] $file = $file.Substring(1, $file.Length - 2).Replace('""', '"') } else { $file = $rest } $file = $file.Replace('$PSScriptRoot', $ScriptRoot) # 若是相对路径,则转换为基于$FilePath的绝对路径 if ($file -notmatch "^[a-zA-Z]:") { $file = "$ScriptRoot/$file" } if (!(Test-Path $file -PathType Leaf)) { return } $file } $Content = $Result | # 处理#_!!<line> ForEach-Object { if ($_ -match "^(\s*)#_!!(?<line>.*)") { $Matches[1] + $Matches["line"] } else { $_ } } | # 处理#_include <file>、#_include_as_value <valuename> <file> ForEach-Object { if ($_ -match "^\s*#_include\s+(?<rest>.+)\s*") { $file = GetIncludeFilePath $Matches["rest"] if (!$file) { return } ReadScriptFile $file } elseif ($_ -match "^\s*#_include_as_value\s+(?<valuename>[a-zA-Z_][a-zA-Z_0-9]+)\s+(?<rest>.+)\s*") { $valuename = $Matches["valuename"] $file = GetIncludeFilePath $Matches["rest"] if (!$file) { return } Write-Host "Reading file $([System.IO.Path]::GetFileName($File)) size $((Get-Item $File).Length) bytes" $IncludeContent = Get-Content -LiteralPath $file -Encoding UTF8 -ErrorAction SilentlyContinue if (-not $IncludeContent) { Write-Error "No data found. May be read error or file protected." return } $IncludeContent = $IncludeContent -join "`n" $IncludeContent = $IncludeContent.Replace("'", "''") "`$$valuename = '$IncludeContent'" } else { if ($_ -match '^\s*.\s*(?<rest>(\"|)\$PSScriptRoot.+)\s*') { $file = GetIncludeFilePath $Matches["rest"] if ($file) { return ReadScriptFile $file } } elseif ($_ -match '^\s*&\s*(?<rest>(\"|)\$PSScriptRoot.+)\s*') { $file = GetIncludeFilePath $Matches["rest"] if ($file) { return @('&{', $(ReadScriptFile $file), '}') } } $_ } } $Content -join "`n" } |