代码之家  ›  专栏  ›  技术社区  ›  ElektroStudios

在控制台底部窗口显示Add AppxPack进度条

  •  1
  • ElektroStudios  · 技术社区  · 3 年前

    在PowerShell v5.0中,如何在底部控制台窗口显示Add-AppxPack的cmdlet进度条而不是以下内容?:

    enter image description here

    进度条隐藏了我在控制台的开始/顶部编写的信息输出。

    我向ChatGPT AI提出了这个问题,但它无法理解这个问题。

    这是我正在使用的完整代码(几乎所有这些代码都是由ChatGPT生成的):

    # AppX Automated Package Installer
    
    # Takes a string input of an AppX package name and parses it to extract the name, version, architecture, and publisher ID. 
    # It uses regular expressions to match the package string pattern and returns a custom object with the parsed information. 
    # If the input string cannot be parsed, an error is thrown.
    function Get-PackageInfo {
        param (
            [Parameter(Mandatory=$true)]
            [string]$PackageString
        )
    
        $dirname = [System.IO.Path]::GetDirectoryName($PackageString)
        if ([string]::IsNullOrEmpty($dirname)) {
            $dirname = $PWD
        }
    
        $filename = [System.IO.Path]::GetFileName($PackageString) -replace "(?i)\.Appx$", ""
    
        $regex = '^(?<Name>.+?)_(?<Version>.+?)_(?<Architecture>.+?)__(?<PublisherId>.+)$'
        $match = $filename -match $regex
    
        if (!$match) {
            throw "Unable to parse the string package: '$PackageString'"
        }
    
        $packageName = $matches['Name']
        $packageVersion = $matches['Version']
        $packageArchitecture = $matches['Architecture']
        $packagePublisherId = $matches['PublisherId']
        $packageFullName = "${packageName}_${packageVersion}_${packageArchitecture}__${packagePublisherId}"
        $packageFullPath = [System.IO.Path]::Combine($dirname, "$filename.Appx")
    
        [PSCustomObject]@{
            Name = $packageName
            Version = $packageVersion
            Architecture = $packageArchitecture
            PublisherId = $packagePublisherId
            FullName = $packageFullName
            FullPath = $packageFullPath
        }
    }
    
    $packageString = "Microsoft.VP9VideoExtensions_1.0.52781.0_x64__8wekyb3d8bbwe.Appx"
    $sourcePackage = Get-PackageInfo -PackageString $packageString
    
    
    Write-Output "Source Package Info:"
    Write-Output "Package String.....: $packageString"
    Write-Output "Package Full Path..: $($sourcePackage.FullPath)"
    Write-Output "Full Name..........: $($sourcePackage.FullName)"
    Write-Output "Name...............: $($sourcePackage.Name)"
    Write-Output "Version............: $($sourcePackage.Version)"
    Write-Output "Architecture.......: $($sourcePackage.Architecture)"
    Write-Output "Publisher Id.......: $($sourcePackage.PublisherId)"
    Write-Output ""
    
    Write-Output "Checking if source package it is already installed..."
    Write-Output ""
    $packages = Get-AppxPackage "$($sourcePackage.Name)*" -ErrorAction SilentlyContinue
    foreach ($package in $packages) {
        if ($package.Version -eq $sourcePackage.Version -and $package.Architecture -eq $sourcePackage.Architecture) {
            Write-Warning "Source package $($sourcePackage.Name) v$($sourcePackage.Version) ($($sourcePackage.Architecture)) is already installed."
            Write-Warning "Installation is not needed."
            Write-Output ""
            Write-Output "Program will terminate now. Press any key to exit..."
            $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
            Exit 0
        }
    }
    
    Write-Output "Source package $($sourcePackage.Name) v$($sourcePackage.Version) ($($sourcePackage.Architecture)) is ready to be installed."
    Write-Output ""
    
    Write-Output "Installing source package..."
    Write-Output ""
    try {
        Add-AppxPackage -Path "$($sourcePackage.FullPath)" -ErrorAction Stop
        Write-Host "The source package $($sourcePackage.Name) v$($sourcePackage.Version) ($($sourcePackage.Architecture)) has been successfully installed." -BackgroundColor Black -ForegroundColor Green 
        Write-Output ""
        Write-Output "Program will terminate now. Press any key to exit..."
        $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
        Exit 0
    }
    catch {
        Write-Host "Error installing source package $($sourcePackage.Name) v$($sourcePackage.Version) ($($sourcePackage.Architecture))"  -BackgroundColor Black -ForegroundColor Red
        Write-Output ""
        Write-Output ""
        Write-Error -Message ($_.Exception | Format-List * -Force | Out-String)
        Write-Output ""
        Write-Output "Program will terminate now. Press any key to exit..."
        $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
        Exit 1
    }
    
    0 回复  |  直到 3 年前
        1
  •  0
  •   ElektroStudios    3 年前

    请随意发布与此不同的其他答案,并将其标记为已接受的答案。


    这只是代码的更新,应用了@Santiago Squarzon的变通方法:

    # --------------------------------------------- #
    # AppX Automated Package Installer - by Elektro #
    # --------------------------------------------- #
    
    # This script will find any AppX package files within the current directory (without recursion),
    # print info about the package, print a message in case of the package is already installed,
    # and install the package in case of it is not installed, handling errors during installation.
    
    # ---------------------------------------------------------------------
    
    # Takes a string argument that points to an AppX package name or file,
    # then it uses a regular expression to match the package string pattern
    # and returns a custom object with the Name, Version, Architecture,
    # PublisherId and other properties.
    #
    # Parameters:
    #   -PackageString: A string that points to the file name
    #                   or full path of an AppX package file.
    #
    # Returns:
    #   A PSCustomObject object with these properties defined:
    #     [String] Name
    #     [String] Version
    #     [String] Architecture
    #     [String] PublisherId
    #     [String] FullName
    function Get-AppXPackageInfo {
        param (
            [Parameter(Mandatory=$true)] [string]$PackageString
        )
    
        #$dirname = [System.IO.Path]::GetDirectoryName($PackageString)
        #if ([string]::IsNullOrEmpty($dirname)) {
        #    $dirname = $PWD
        #}
    
        $filename = [System.IO.Path]::GetFileName($PackageString) -replace "(?i)\.Appx$", ""
    
        $regex = '^(?<Name>.+?)_(?<Version>.+?)_(?<Architecture>.+?)__(?<PublisherId>.+)$'
        $match = $filename -match $regex
    
        if (!$match) {
            throw "Unable to parse the string package: '$PackageString'"
        }
    
        [string]$packageName         = $matches['Name']
        [string]$packageVersion      = $matches['Version']
        [string]$packageArchitecture = $matches['Architecture']
        [string]$packagePublisherId  = $matches['PublisherId']
        [string]$packageFullName     = "${packageName}_${packageVersion}_${packageArchitecture}__${packagePublisherId}"
        #[string]$packageFullPath    = [System.IO.Path]::Combine($dirname, "$filename.Appx")
    
        [PSCustomObject]@{
            Name = $packageName
            Version = $packageVersion
            Architecture = $packageArchitecture
            PublisherId = $packagePublisherId
            FullName = $packageFullName
            #FullPath = $packageFullPath
        }
    }
    
    # Determines whether an Appx package matching the specified
    # name, version and architecture is installed in the system.
    #
    # Parameters:
    #   -Name........: The package name.
    #   -Version.....: The package version.
    #   -Architecture: The package architecture ("x86", "x64").
    #
    # Returns:
    #   $true if the AppX package is installed in the system,
    #   $false otherwise.
    function IsAppxPackageInstalled() { 
        param (
            [Parameter(Mandatory=$true)] [string]$name,
            [Parameter(Mandatory=$true)] [string]$version,
            [Parameter(Mandatory=$true)] [string]$architecture
        )
    
        $packages = Get-AppxPackage "$($name)*" -ErrorAction Stop | Where-Object { 
            $_.Name.ToLower()              -eq $name.ToLower()         -and 
            $_.Version.ToLower()           -eq $version.ToLower()      -and 
            "$($_.Architecture)".ToLower() -eq $architecture.ToLower()
        }
        return ($packages.Count -gt 0)
    }
    
    # -----------------------------------------------------------------------------------
    
    $host.ui.RawUI.WindowTitle = "AppX Automated Package Installer - by Elektro"
    
    # Hides the progress-bar of 'Add-AppxPackage' cmdlet for this script.
    # Thanks to @Santiago Squarzon for the tip: https://stackoverflow.com/questions/75716867
    $ProgressPreference = "Ignore"
    
    Do {
        Clear-Host
        Write-Output " * * * * * * * * * * * * * * * * * * * * * * * "
        Write-Output ""
        Write-Output " AppX Automated Package Installer - by Elektro "
        Write-Output ""
        Write-Output " * * * * * * * * * * * * * * * * * * * * * * * "
        Write-Output ""
        Write-Output " This script will find any AppX package files within the current directory (without recursion),"
        Write-Output " print info about the package, print a message in case of the package is already installed,"
        Write-Output " and install the package in case of it is not installed, handling errors during installation."
        Write-Output " _________________________________________________________________"
        Write-Output ""
        Write-Host "-Continue? (Y/N)"
        $key = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
        $char = $key.Character.ToString().ToUpper()
    } while ($char -ne "Y" -and $char -ne "N")
    
    if ($char -eq "N") {Exit 1} 
    Clear-Host
    
    $appxFiles = Get-ChildItem -Path "$PWD" -Filter "*.appx"
    
    if ($appxFiles.Count -eq 0) {
        Write-Warning "No Appx files were found in the current directory."
        Write-Output ""
        $LastExitCode = 2
    } else {
        $appxFiles | ForEach-Object {
            # The AppX package string. It can be a file name (with or without extension), or a full path.
            $packageString = $_.FullName
            $packageInfo = Get-AppXPackageInfo -PackageString $packageString
            $nameVerArch = "$($packageInfo.Name) v$($packageInfo.Version) ($($packageInfo.Architecture))"
            Write-Host "Package Info.:" -ForegroundColor Gray
            Write-Host ($packageInfo | Format-List | Out-String).Trim() -ForegroundColor DarkGray
            Write-Output ""
    
            $isInstalled = IsAppxPackageInstalled -Name $packageInfo.Name -Version $packageInfo.Version -Architecture $packageInfo.Architecture
            if ($isInstalled) {
                Write-Warning "Package $nameVerArch is already installed."
                Write-Warning "Installation is not needed."
            } else {
                Write-Output "Package $nameVerArch is ready to install."
                Write-Output "Installing package..."
                try {
                    Add-AppxPackage -Path "$($_.FullName)" -ErrorAction Stop
                    Write-Host "Package $nameVerArch has been successfully installed." -BackgroundColor Black -ForegroundColor Green 
                } catch {
                    Write-Host "Error installing package $nameVerArch" -BackgroundColor Black -ForegroundColor Red
                    Write-Output ""
                    Write-Error -Message ($_.Exception | Format-List * -Force | Out-String)
                    $LastExitCode = 1
                    Break
                }
            }
            Write-Output ""
            $LastExitCode = 0
        }
    }
    
    Write-Output "Program will terminate now with exit code $LastExitCode. Press any key to exit..."
    $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
    Exit $LastExitCode
    
    推荐文章