This is the Windows Package Manager (WinGet) CLI client - a native Windows application for discovering and installing packages. The codebase consists of:
- C++/WinRT client (
src/AppInstallerCLI*) - The main CLI and core logic - COM API (
src/Microsoft.Management.Deployment) - Public Windows Runtime API for programmatic access - PowerShell modules (
src/PowerShell) - Microsoft.WinGet.Client and Microsoft.WinGet.Configuration cmdlets - Configuration system - DSC-based system configuration using WinGet
Use a configuration file in .config as in winget configure .config/configuration.winget (alternatives provided for other VS SKUs).
Manual steps:
- Install Visual Studio 2022 with required workloads (see
.vsconfig) - Install Windows SDK 10.0.26100:
winget install Microsoft.WindowsSDK.10.0.26100 - Enable developer mode in Windows
- Run
vcpkg integrate installfrom Developer Command Prompt
Open src\AppInstallerCLI.sln in Visual Studio and build the solution (Ctrl+Shift+B) or use msbuild.exe to build from the command line.
The solution uses:
- MSBuild
- vcpkg for C++ dependencies
- NuGet for C++ and .NET dependencies
- Deploy solution: Build > Deploy Solution
- Run from command line:
wingetdev - For debugging:
- Right-click
AppInstallerCLIPackage> Properties > Debug tab - Set Debugger type to "Native Only" for both Application and Background task processes
- Select "Do not launch, but debug my code when it starts"
- Press F5 and run
wingetdevin a separate terminal
- Right-click
Entry point: src/AppInstallerCLI/main.cpp
Located in AppInstallerCLITests project. After building:
# Run all tests
src\<ARCH>\<Debug|Release>\AppInstallerCLITests\AppInstallerCLITests.exe
# Run specific test
src\<ARCH>\<Debug|Release>\AppInstallerCLITests\AppInstallerCLITests.exe TestName
# Available options
AppInstallerCLITests.exe --helpMicrosoft.WinGet.UnitTests- PowerShell module testsMicrosoft.Management.Configuration.UnitTests- Configuration system testsWinGetUtilInterop.UnitTests- Interop layer tests
AppInstallerCLIE2ETests project contains end-to-end integration tests.
AppInstallerCLICore - Core CLI logic organized around:
- ExecutionContext: State container that flows through workflows. Contains arguments, reporter, flags, and data (ExecutionContextData.h)
- Workflows: Composable functions that take ExecutionContext and perform operations (e.g., InstallFlow, UpdateFlow, SearchFlow)
- Commands: Parse arguments and orchestrate workflows
- Reporter: Handles all user output (ExecutionReporter.h)
AppInstallerRepositoryCore - Package source abstraction:
- Interfaces for different source types (REST, SQLite index, Microsoft Store, composite)
- Search, match, and correlation logic
- Package version selection and dependencies
AppInstallerCommonCore - Shared utilities:
- Manifest parsing (YAML/JSON)
- Settings and group policy
- Telemetry and logging
- HTTP client, downloader, archive handling
Microsoft.Management.Deployment - COM API surface:
- IDL definitions in
PackageManager.idl - WinRT projections for external consumption
- Used by PowerShell modules and third-party integrations
AppInstallerCLIPackage - Dev MSIX package definition:
- Models the release package definition as closely as possible.
- Contains localized string resources at src\AppInstallerCLIPackage\Shared\Strings\en-us\winget.resw
Workflow Pattern: Functions that operate on ExecutionContext:
void WorkflowTask(Execution::Context& context)
{
// Check if already terminated
AICLI_RETURN_IF_TERMINATED(context);
// Access data
auto& data = context.Get<Data::Installer>();
// Report to user
context.Reporter.Info() << "Doing something";
// Store data for next workflow
context.Add<Data::SomeResult>(result);
// Terminate on error
if (failed)
{
AICLI_TERMINATE_CONTEXT(HRESULT);
}
}Source Composition: Multiple package sources can be composed:
- CompositeSource combines multiple sources with conflict resolution
- Installed source tracks locally installed packages
- Available sources provide packages to install
Manifest Schema: Package manifests use versioned YAML schemas:
- Schema definitions in
schemas/JSON/manifests/ - Parsing in
AppInstallerCommonCore/Manifest/ - Multi-file manifests: installer, locale, version, defaultLocale
-
Namespace structure:
AppInstaller::<Area>[::<Subarea>]AppInstaller::CLI::Execution- CLI execution contextAppInstaller::CLI::Workflow- Workflow functionsAppInstaller::Repository- Repository/source logicAppInstaller::Manifest- Manifest typesAppInstaller::Settings- User/admin settings
-
Macros: Prefixed with
AICLI_for CLI,WINGET_for general -
Data keys: ExecutionContextData uses enum keys to type-safely store/retrieve data
- Use Windows-style paths with backslashes (
\) - Leverage WinRT APIs via C++/WinRT projections
- COM threading models matter - client uses multi-threaded apartment (MTA)
- Package deployment uses Windows App SDK / MSIX infrastructure
- Requires Windows 10 1809+ (build 17763)
- Review
CONTRIBUTING.mdfor workflow - File/discuss issues before starting work
- Specs required for features (stored in
doc/specs/) - Follow existing code style (see
stylecop.json) - CI runs on Azure Pipelines (
azure-pipelines.yml)
# Get WinGet client info
wingetdev --info
# Show experimental features
wingetdev features
# Check sources
wingetdev source listThe English resource file src\AppInstallerCLIPackage\Shared\Strings\en-us\winget.resw is the only file contributors should edit for string changes. It feeds the Microsoft localization pipeline.
The files under Localization\Resources\<locale>\ are automatically synced from Microsoft's internal localization system and must not be edited. Any manual edits will be overwritten on the next sync.
Every string that could be misunderstood without context should have a <comment>.
- Changing a string's
<value>automatically queues it for retranslation on the next localization sync. - Changing only a
<comment>does NOT trigger retranslation. Comments improve future translations but do not fix existing ones.
To fix an existing bad translation, a bug has to be filed internally with the localization team.