https://docs.microsoft.com/zh-cn/windows/package-manager/
Windows程序包管理器(Windows Package Manager
,简称Winget
)是一个综合的程序包管理器解决方案,由一个命令行工具和一组用于在Windows 10/11上安装应用程序的服务组成。它由一个命令行实用程序(CLI)和一组安装应用程序的服务组成。独立软件供应商可以将其作为软件包的分发渠道。
通常来说,在Windows上我们要安装和下载软件,可能会打开搜索引擎去搜索它,有经验的人可以快速识别软件的官网,而其他小白,可能会前往各种充满广告或陷阱的下载站,甚至最终折腾下来下载到的是夹带了木马的软件,好不容易得到安装包,我们还要经受一轮选择题的考验,不断地下一步安装流程和稍不留神就中招的默认勾选项,都会让你肉颤心惊,过五关,斩六将,即使身经百战的高手也不见得每次都可以毫发无损的完成安装。
而且,如果是有一百台电脑需要部署,那么重复上诉流程会让人感到奔溃,效率极其低下。
那么在Linux上,通常怎么解决上诉问题的?比如我们熟悉的Linux发行版Ubuntu、Linux Mint、Elementary OS的母版都是具有强健包管理器的Debian系统,它的每个组件和应用程序都内置在系统中安装的软件包中,Debian使用一套名为Advanced Packaging Tool
(APT
)的工具来管理这种包系统。
大多数现代类Unix操作系统都提供了一个集中的软件包管理机制,以帮助用户搜索、安装和管理软件。而软件通常以包的形式存储在仓库(Repository)中,对软件包的使用和管理被称为包管理。而Linux包的基本组成部分通常有:共享库、应用程序、服务和文档。
所以,如果在Windows上也拥有一套包管理器,那么搜索、安装、管理软件的效率会翻几倍,而且还更加安全。
Winget正是这么响应时代的号召而生,为更高效安全的软件维护而生。
https://github.com/microsoft/winget-pkgs
"Winget-Cli客户端"时围绕包源的概念构建的,由包源提供发现和检索有关包元数据的能力,使"Winget-Cli客户端"能采取相应的动作。
默认来源是来自"Windows Package Manager Community Repository"社区提供的数据。
https://github.com/microsoft/winget-cli/ 开源软件,贡献力量,你必须先同意并签署Microsoft CLA
要求Windows 10 1809 (build 17763) 及更新版本,或者Windows 11全部版本
Winget
的商店版是内置到"应用安装程序(App Installer
)"中的,所以从商店我们只需要安装最新的"应用安装程序(App Installer
)"即可,Winget
的更新也将随"应用安装程序(App Installer
)"商店版一起更新。
ms-windows-store://pdp/?productid=9NBLGGH4NNS1
如果已安装,请确保更新到最新版本。
https://github.com/microsoft/winget-cli/releases
和商店版相同的发布包也将Winget-Cli
项目GitHub Releases
处被发布,这里我们找到.msixbundle
格式的安装包文件进行下载安装。
下载完成之后,双击安装。
在一些较老的Windows 10版本,如果你安装遇到了错误提示,可能你还需要额外安装"适用于开发人员的C++运行时框架桌面桥(
VC++ v14 Desktop Framework Package
)",它的安装包地址如下:
安装成功之后,可以在"Windows终端"中通过执行如下命令来验证:
winget
https://docs.microsoft.com/zh-cn/windows/package-manager/winget/search
winget search $Keyword
第一次使用搜索,可能提示"是否同意所有源协议条款?",这里回答Y
即可。
默认情况下搜索不区分大小写
winget search micro
限定应用程序Id
winget search --id $AppId
限定应用名称
winget search --name $AppName
限定应用标记
winget search --tag $AppTag
按源进行筛选
winget search $Keyword -s $SoureName
https://docs.microsoft.com/zh-cn/windows/package-manager/winget/source
默认包源存储库
Windows程序包管理器会指定两个默认存储库:
msstore
- Microsoft Store目录。winget
- Windows程序包管理器应用存储库。包源协议
单个源可以请求用户在访问存储库之前同意条款。在添加或使用存储库之前,用户必须同意提供的条款。
列举所有包源
winget source list
添加指定源信息
winget source add --name $SourceName $SourceUrl
查看源详细信息
winget source list --name $SourceName
更新指定源的包索引
winget source update --name $SourceName
更新所有的源的包索引
winget source update
删除指定源
需要使用Windows终端的管理员模式执行
winget source remove --name $SourceName
强制重置所有的源设置
需要使用Windows终端的管理员模式执行,并且携带强制参数
winget source reset --force
导出源信息
winget source export --name $SourceName
https://docs.microsoft.com/zh-cn/windows/package-manager/winget/install
指定包Id进行安装
winget install --id $PackageId
例如:
winget install --id Microsoft.PowerToys
指定软件版本进行安装(--version)
winget install $PackageName -v $TargetVersion
例如:
winget install powertoys --version 0.15.2
指定包Id及包版本进行安装
winget install --id $PackageId --version $TargetVersion
例如:
winget install --id Microsoft.PowerToys --version 0.15.2
指定安装源进行安装
winget install $PackageName -s $SourceName
例如:
winget install powertoys -s msstore
在指定源指定Id进行安装
winget install --id $PackageId -s $SourceName
例如:
winget install --id Git.Git -e -source winget
指定字符串精确查找(--exact)
winget install $PackageName -e
以交互模式显示安装进度(--interactive)
winget install $PackageName -i
以静默模式进行安装(--silent)
winget install $PackageName -h
安装并写入日志(--log)
winget install $PackageName -o $LogFilePath
值得注意的是安装日志的默认存储位置位于:%temp%\AICLI\*.log
指定安装位置(--location)
winget install $PackageName -l $LocationPath
强制安装绕过哈希检查(--force)
winget install $PackageName --force
指定本地包描述文件进行安装(--manifest)
winget install -m $PackageManifestPath
基于本地文件安装是比较有风险的,默认不会允许,如果需要开启通过如下命令开启:
winget settings --enable LocalManifestFiles
若关闭这个权限可运行:
winget settings --disable LocalManifestFiles
对于来自微软商店的包指定Id进行安装
微软商店的包源通常采用唯一标识符作为包的Id,可以直接用程序在商店的Store Id
来作为安装Id
winget install $StoreId -s msstore
例如:
winget install XP9KHM4BK9FZ7Q -s msstore
自动接受询问的安装许可协议(--accept-package-agreements)
某些应用程序在安装时要求用户在安装前同意许可协议或其他协议。发生这种情况时,Windows程序包管理器会提示用户同意协议。如果用户不同意,则应用程序不会安装,编写脚本可以用到它。
winget install $PackageName --accept-package-agreements
例如:
winget install XP9KHM4BK9FZ7Q --accept-package-agreements -s msstore
自动接受询问的源许可协议(--accept-source-agreements)
对于有些包源第一次使用时,是会询问源许可协议的,如果需要自动接受它,可以用这个参数,编写脚本可以用到它。
winget install $PackageName --accept-source-agreements
例如:
winget install XP9KHM4BK9FZ7Q --accept-source-agreements -s msstore
使用彩虹样式进度条(--rainbow)
携带参数--rainbow
可以在安装时使用彩虹样式的进度条。
winget install $PackageName --rainbow
例如:
winget install Microsoft.dotNetFramework --version 4.7.1 --rainbow
https://docs.microsoft.com/zh-cn/windows/package-manager/winget/uninstall
指定应用Id进行卸载
winget uninstall --id "$AppId"
如果你不知道当前应用的Id,可以先通过List来获取,从结果中可获取到该应用的Id
winget list $AppName
指定应用名称和版本进行卸载
winget uninstall --name $AppName --version $AppVersion
自动接受询问的源许可协议(--accept-source-agreements)
winget uninstall --id "$AppId" --accept-source-agreements
指定字符串精确查找(--exact)
winget uninstall --id "$AppId" -e
以交互模式显示卸载进度(--interactive)
winget uninstall --id "$AppId" -i
以静默模式进行卸载(--silent)
winget uninstall --id "$AppId" -h
卸载并写入日志(--log)
winget uninstall --id "$AppId" -o $LogFilePath
值得注意的是安装日志的默认存储位置位于:%temp%\AICLI\*.log
https://docs.microsoft.com/zh-cn/windows/package-manager/winget/upgrade
指定应用Id进行升级
winget upgrade --id "$AppId"
如果你不知道当前应用的Id,可以先通过List来获取,从结果中可获取到该应用的Id
winget list $AppName
指定应用名称和版本进行升级
winget upgrade $AppName --version $AppVersion
升级所有的已安装应用
将所有可用的包更新为最新的应用程序
winget upgrade --all
自动接受询问的升级许可协议(--accept-package-agreements)
某些应用程序在升级时要求用户在安装前同意许可协议或其他协议。发生这种情况时,Windows程序包管理器会提示用户同意协议。如果用户不同意,则应用程序不会升级,编写脚本可以用到它。
winget upgrade --id "$AppId" --accept-package-agreements
例如:
winget upgrade --id "XP9KHM4BK9FZ7Q" --accept-package-agreements -s msstore
自动接受询问的源许可协议(--accept-source-agreements)
对于有些包源第一次使用时,是会询问源许可协议的,如果需要自动接受它,可以用这个参数,编写脚本可以用到它。
winget upgrade --id "$AppId" --accept-source-agreements
例如:
winget upgrade --id "XP9KHM4BK9FZ7Q" --accept-source-agreements -s msstore
https://docs.microsoft.com/zh-cn/windows/package-manager/winget/show
指定应用Id进行获取应用详情
winget show --id "$AppId"
如果你不知道当前应用的Id,可以先通过List来获取,从结果中可获取到该应用的Id
winget list $AppName
应用详情元数据清单
值 | 说明 |
---|---|
Id | 应用程序的ID。 |
名称 | 应用程序的名称。 |
Publisher | 应用程序的发布者。 |
版本 | 应用程序的版本。 |
Author | 应用程序的作者。 |
AppMoniker | 应用程序的AppMoniker。 |
描述 | 应用程序的说明。 |
许可证 | 应用程序的许可证。 |
LicenseUrl | 应用程序的许可证文件的URL。 |
Homepage | 应用程序的主页。 |
Tags | 为协助搜索提供的标记。 |
命令 | 应用程序支持的命令。 |
Channel | 有关应用程序是预览版还是发行版的详细信息。 |
Minimum OS Version | 应用程序支持的最低OS版本。 |
安装程序详细信息
值 | 说明 |
---|---|
Arch | 安装程序的体系结构。 |
语言 | 安装程序的语言。 |
Installer Type | 安装程序的类型。 |
Download Url | 安装程序的URL。 |
Hash | 安装程序的Sha-256。 |
Scope | 显示安装程序是针对每台计算机还是针对每个用户。 |
https://docs.microsoft.com/zh-cn/windows/package-manager/winget/hash
指定本地文件创建文件哈希(--file)
winget hash -f $AppFilePath
指定本地文件创建哈希和签名SHA256(--msix)
指定hash命令还会创建可以与MSIX安装程序配合使用的SHA 256 SignatureSha256
winget hash -m -f $AppFilePath
https://docs.microsoft.com/zh-cn/windows/package-manager/winget/features
查看实验性功能
winget features
https://docs.microsoft.com/zh-cn/windows/package-manager/winget/settings
设置配置文件位置
%LOCALAPPDATA%\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState\settings.json
或者
%LOCALAPPDATA%\Microsoft\WinGet\Settings\settings.json
打开设置文件
winget settings
开启某项功能(--enable)
winget settings --enable $FeatureName
关闭某项功能(--disable)
winget settings --disable $FeatureName
https://docs.microsoft.com/zh-cn/windows/package-manager/winget/validate
验证指定路径清单文件(--manifest)
winget validate --manifest $ManifestFilePath
https://docs.microsoft.com/zh-cn/windows/package-manager/winget/troubleshooting
默认情况下,Windows程序包管理器会在执行命令时创建日志文件。这些日志文件位于此处:
%LOCALAPPDATA%\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState\DiagOutputDir
可以在原命令尾部追加--verbose-logs
,可以记录更全面的日志文件(它们提供与CDN和源的完整通信)。
例如:
winget install vscode --verbose-logs
winget search -n visual --verbose-logs
winget source add -n mysource -t Microsoft.REST -a https://www.contoso.org --verbose-logs
可以编写批处理脚本和PowerShell脚本来安装多个应用程序
@echo off
Echo Install Powertoys and Terminal
REM Powertoys
winget install Microsoft.Powertoys
if %ERRORLEVEL% EQU 0 Echo Powertoys installed successfully.
REM Terminal
winget install Microsoft.WindowsTerminal
if %ERRORLEVEL% EQU 0 Echo Terminal installed successfully. %ERRORLEVEL%
使用脚本时,winget会按指定顺序启动应用程序。当安装程序返回成功或失败时,winget会启动下一个安装程序。如果某个安装程序启动了另一进程,它可能会提前返回到winget。这会导致winget在上一个安装程序完成之前安装下一个安装程序。
安装程序的行为可能会有所不同,具体取决于你是否是以管理员权限运行winget。
winget工具的当前预览版支持以下类型的安装程序:
https://github.com/microsoft/winget-create
https://docs.microsoft.com/zh-cn/windows/package-manager/package/manifest
a. 学习构建程序包清单的YAML格式
如果要将软件包提交到Windows程序包管理器存储库,请首先创建程序包清单。清单是描述要安装的应用程序的YAML文件,之所以选择YAML格式作为程序包清单格式,是因为人类可以相当容易地阅读它,并且这样可与其他Microsoft开发工具保持一致。
如果不熟悉YAML语法,可以通过在Y分钟内学会YAML来学习基础知识。
程序包清单必须包含一组必需的项,还可以进一步包含可选项以帮助改善客户在安装软件时的体验。清单文件中的每个字段都必须采用Pascal大小写形式,并且不能重复。
b. Yaml格式清单最小结构
PackageIdentifier: # Publisher.package format.
PackageVersion: # Version numbering format.
PackageLocale: # BCP 47 format (e.g. en-US)
Publisher: # The name of the publisher.
PackageName: # The name of the application.
License: # The license of the application.
ShortDescription: # The description of the application.
Installers:
- Architecture: # Enumeration of supported architectures.
InstallerType: # Enumeration of supported installer types (exe, msi, msix, inno, wix, nullsoft, appx).
InstallerUrl: # Path to download installation file.
InstallerSha256: # SHA256 calculated from installer.
ManifestType: # The manifest file type
ManifestVersion: 1.0.0
比如:
路径:
manifests/m/Microsoft/WindowsTerminal/1.6.10571.0/Microsoft.WindowsTerminal.yaml
PackageIdentifier: Microsoft.WindowsTerminal
PackageVersion: 1.6.10571.0
PackageLocale: en-US
Publisher: Microsoft
PackageName: Windows Terminal
License: MIT
ShortDescription: The new Windows Terminal, a tabbed command line experience for Windows.
Installers:
- Architecture: x64
InstallerType: msix
InstallerUrl: https://github.com/microsoft/terminal/releases/download/v1.6.10571.0/Microsoft.WindowsTerminal_1.6.10571.0_8wekyb3d8bbwe.msixbundle
InstallerSha256: 092aa89b1881e058d31b1a8d88f31bb298b5810afbba25c5cb341cfa4904d843
SignatureSha256: e53f48473621390c8243ada6345826af7c713cf1f4bbbf0d030599d1e4c175ee
ManifestType: singleton
ManifestVersion: 1.0.0
c. 多个清单文件
为了提供最佳用户体验,清单应包含尽可能多的元数据。为了区分验证安装程序和提供本地化元数据的问题,应将清单拆分为多个文件。此类清单至少需要3个YAML文件。还应提供其他区域设置。
例如一个版本文件
路径:
manifests/m/Microsoft/WindowsTerminal/1.6.10571.0/Microsoft.WindowsTerminal.yaml
PackageIdentifier: "Microsoft.WindowsTerminal"
PackageVersion: "1.6.10571.0"
DefaultLocale: "en-US"
ManifestType: "version"
ManifestVersion: "1.0.0"
例如一个默认区域设置文件
路径:
manifests/m/Microsoft/WindowsTerminal/1.6.10571.0/Microsoft.WindowsTerminal.locale.en-US.yaml
PackageIdentifier: "Microsoft.WindowsTerminal"
PackageVersion: "1.6.10571.0"
PackageLocale: "en-US"
Publisher: "Microsoft"
PublisherUrl: "https://www.microsoft.com/"
PrivacyUrl: "https://privacy.microsoft.com/"
PackageName: "Windows Terminal"
PackageUrl: "https://docs.microsoft.com/windows/terminal/"
License: "MIT"
LicenseUrl: "https://github.com/microsoft/terminal/blob/master/LICENSE"
ShortDescription: "The new Windows Terminal, a tabbed command line experience for Windows."
Tags:
- "Console"
- "Command-Line"
- "Shell"
- "Command-Prompt"
- "PowerShell"
- "WSL"
- "Developer-Tools"
- "Utilities"
- "cli"
- "cmd"
- "ps"
- "terminal"
ManifestType: "defaultLocale"
ManifestVersion: "1.0.0"
例如一个其他区域设置文件
路径:
manifests/m/Microsoft/WindowsTerminal/1.6.10571.0/Microsoft.WindowsTerminal.locale.fr-FR.yaml
PackageIdentifier: "Microsoft.WindowsTerminal"
PackageVersion: "1.6.10571.0"
PackageLocale: "fr-FR"
Publisher: "Microsoft"
ShortDescription: "Le nouveau terminal Windows, une expérience de ligne de commande à onglets pour Windows."
ManifestType: "locale"
ManifestVersion: "1.0.0"
例如一个安装程序文件
路径:
manifests/m/Microsoft/WindowsTerminal/1.6.10571.0/Microsoft.WindowsTerminal.installer.yaml
PackageIdentifier: "Microsoft.WindowsTerminal"
PackageVersion: "1.6.10571.0"
Platform:
- "Windows.Desktop"
MinimumOSVersion: "10.0.18362.0"
InstallerType: "msix"
InstallModes:
- "silent"
PackageFamilyName: "Microsoft.WindowsTerminal_8wekyb3d8bbwe"
Installers:
- Architecture: "x64"
InstallerUrl: "https://github.com/microsoft/terminal/releases/download/v1.6.10571.0/Microsoft.WindowsTerminal_1.6.10571.0_8wekyb3d8bbwe.msixbundle"
InstallerSha256: 092aa89b1881e058d31b1a8d88f31bb298b5810afbba25c5cb341cfa4904d843
SignatureSha256: e53f48473621390c8243ada6345826af7c713cf1f4bbbf0d030599d1e4c175ee
- Architecture: "arm64"
InstallerUrl: "https://github.com/microsoft/terminal/releases/download/v1.6.10571.0/Microsoft.WindowsTerminal_1.6.10571.0_8wekyb3d8bbwe.msixbundle"
InstallerSha256: 092aa89b1881e058d31b1a8d88f31bb298b5810afbba25c5cb341cfa4904d843
SignatureSha256: e53f48473621390c8243ada6345826af7c713cf1f4bbbf0d030599d1e4c175ee
- Architecture: "x86"
InstallerUrl: "https://github.com/microsoft/terminal/releases/download/v1.6.10571.0/Microsoft.WindowsTerminal_1.6.10571.0_8wekyb3d8bbwe.msixbundle"
InstallerSha256: 092aa89b1881e058d31b1a8d88f31bb298b5810afbba25c5cb341cfa4904d843
SignatureSha256: e53f48473621390c8243ada6345826af7c713cf1f4bbbf0d030599d1e4c175ee
ManifestType: "installer"
ManifestVersion: "1.0.0"
举个实际的例子(Microsoft.TeamsPreview
)
PackageIdentifier: Microsoft.TeamsPreview
PackageName: Microsoft Teams Preview
Moniker: teams-preview
PackageVersion: 1.4.00.9773
Publisher: Microsoft Corporation
Author: Microsoft Corporation
License: (c) 2021 Microsoft Corporation
LicenseUrl: https://www.microsoft.com/en-us/legal/intellectualproperty/copyright/default
ShortDescription: Meet, chat, call, and collaborate in just one place.
PackageUrl: https://www.microsoft.com/en-us/microsoft-teams/group-chat-software
Installers:
- Architecture: x64
InstallerUrl: https://statics.teams.cdn.office.net/production-windows-x64/1.4.00.9773/Teams_windows_x64.exe
InstallerSha256: f506a167b22437bbfd56316f7a038dc70b2b873dba875f65547a640d84539e73
InstallerType: exe
InstallerSwitches:
Silent: /s
SilentWithProgress: /s
PackageLocale: en-US
ManifestType: singleton
ManifestVersion: 1.0.0
d. 采用不同打包程序实现静默安装参数
安装程序 | 命令 | 文档 |
---|---|---|
MSI | /q | MSI命令行选项 |
InstallShield | /s | InstallShield命令行参数 |
Inno | /SILENT or /VERYSILENT | Inno设置文档 |
Nullsoft | /S | Nullsoft无提示安装程序/卸载程序 |
e. 技巧与最佳做法
vscode
来表示Visual Studio Code
)时会看到与AppMoniker值关联的结果。如果只有一个应用具有指定的AppMoniker值,则客户可以通过指定名字对象(而不是完全限定的包标识符)来安装应用程序。我们可以先通过winget的validate
在本地完成基础的验证,它将验证我们是否符合前面提到的存储库中的清单规范(https://github.com/microsoft/winget-cli/blob/master/doc/ManifestSpecv1.0.md)。
winget validate --manifest $ManifestFilePath
a. 创建Windows程序包管理器存储库的分支
前往Windows程序包管理器存储库项目主页,点击分支(Fork)
按钮,创建一个分支。
b. 克隆并拉取分支
在创建后的分支的主页,点击代码(Code)
按钮,复制HTTPs或者SSH的地址,通过git clone
命令在本地进行克隆和拉取。
git clone https://github.com/YourAccount/winget-pkgs.git
c. 按约定路径添加清单文件
`manifests` / `letter` / `publisher` / `application` / `version` / `Yaml file`
其中:
manifests
文件夹是存储库中所有清单的根文件夹。letter
文件夹是发布者名称的首字母。publisher
文件夹是发布软件的公司的名称。例如:Microsoft
。application
文件夹是应用程序或工具的名称。例如:VSCode
。version
文件夹是应用程序或工具的版本。例如:1.0.0
。YamlFile
是清单的文件名。此文件名必须设置为应用程序的名称和发布者。例如:Contoso.ContosoApp.yaml
注意:
清单中的PackageIdentifier
值必须与清单文件夹路径中的发布者和应用程序名称相匹配,并且清单中的PackageVersion
值必须与文件名中的版本相匹配。
PackageIdentifier: Microsoft.MSIXPackagingTool
PackageVersion: 1.2021.422.0
比如:
manifests\m\Microsoft\MSIXPackagingTool.2021.422.0\Microsoft.MSIXPackagingTool.yaml
d. Git添加并推送到远程
如果你用Visual Studio Code的来编辑最好用自带的来完成。
或者基于如下命令行的步骤
git add manifests\m\Microsoft\MSIXPackagingTool.2021.423.0\Microsoft.MSIXPackagingTool.yaml
git commit -m "Submitting Microsoft.MSIXPackagingTool version 1.2021.423.0.yaml"
git push
e. 创建合并请求PR(Fork方式)
如果你是通过Fork的方式操作的,前往我们Fork后的项目的主页,找到pull requests
页面,点击"创建新拉取合并(new pull request
)"。
接下来,我们将看到Change Files,确认没有问题之后,我们点击右侧的"创建拉取(Create Pull Request
)"按钮
它将提示我们从Fork分支创建一个合并请求到原始项目
接下来,Open a Pull request页面,我们将看到填写描述的地方,这里可以描述一下,没问题之后,点击"创建拉取(Create Pull Request
)"按钮
接下来,会进入提交的流程,机器人会先介入。
f. 创建合并请求PR(Branch方式)
如果你是采用在原项目上新建分支的方式来操作的,在原仓库项目的主页,找到pull requests
页面,点击"创建新拉取合并(new pull request
)"。
g. 签署贡献者授权协议
第一次,机器人可能会提示你,你还没有签署存储库的贡献者授权协议,那么这里我们可以点击Sign Now
处理下。
h.回答提交问卷
i.查看提交验证流程
提交到Windows程序包管理器存储库的所有应用程序都应表现良好,并遵循Windows程序包管理器存储库策略。下面是对提交的一些预期: