Skip to content

fix: Correctly pass value of WingetSourceCustom, Fixes #1043#1135

Open
Salamek wants to merge 8 commits intoRomanitho:developfrom
Salamek:main
Open

fix: Correctly pass value of WingetSourceCustom, Fixes #1043#1135
Salamek wants to merge 8 commits intoRomanitho:developfrom
Salamek:main

Conversation

@Salamek
Copy link

@Salamek Salamek commented Mar 14, 2026

Correctly pass value of WingetSourceCustom, to required functions and replace hardcoded -s 'winget' with -s $src

Proposed Changes

WAU allows to set WAU_WingetSourceCustom registry key to specify what repository should WAU work with, but this key value is used only in few places, in rest it was hardcoded to 'winget' making autoupdates impossible

Related Issues

#1043

@github-actions github-actions bot added the invalid-branch Invalid branch label Mar 14, 2026
@Salamek Salamek changed the base branch from main to develop March 14, 2026 16:01
@github-actions github-actions bot removed the invalid-branch Invalid branch label Mar 14, 2026
@Romanitho
Copy link
Owner

Hi, thanks for your contribution!

Regarding Winget-Install.ps1: the comment mentioning it is 'deprecated' is actually outdated and should be removed. This script was ported from the archived Winget-Install project and is still actively used here. Therefore, feel free to apply your changes to this file as well!

@Salamek
Copy link
Author

Salamek commented Mar 21, 2026

Ok i have added -Source parameter to Winget-Install that defaults to 'winget' when not provided

Remove deprecated notes regarding standalone usage and GitHub link.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes WAU’s handling of a custom WinGet source (WAU_WingetSourceCustom) by threading the configured source through update-related functions, replacing several hardcoded -s winget usages that prevent upgrades from non-default repositories.

Changes:

  • Pass $Script:WingetSourceCustom into Update-App, and propagate it into Get-AppInfo and Confirm-Installation.
  • Replace hardcoded WinGet source arguments with a passed-in $src/$Source in several functions.
  • Adjust workflow permissions for the “Close inactive issues” GitHub Action job.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
Sources/Winget-AutoUpdate/mods/_Mods-Functions.ps1 Adds optional src parameter to mod helper install/uninstall wrappers and uses it in winget calls.
Sources/Winget-AutoUpdate/functions/Update-App.ps1 Adds src parameter and uses it when building winget upgrade/install params; forwards to helper functions.
Sources/Winget-AutoUpdate/functions/Get-AppInfo.ps1 Adds src parameter and uses it in winget show.
Sources/Winget-AutoUpdate/functions/Confirm-Installation.ps1 Adds src parameter and uses it in winget export.
Sources/Winget-AutoUpdate/Winget-Upgrade.ps1 Passes configured custom source into Update-App.
Sources/Winget-AutoUpdate/Winget-Install.ps1 Introduces a Source parameter and attempts to apply it in install/uninstall flows (currently with blocking issues).
.github/workflows/GA_Close-Inactive-Issues.yml Expands job token permissions to include contents: write.

Salamek and others added 3 commits March 23, 2026 19:28
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
$Source, use array for $WingetArgs since parameters could also contain
spaces and that would break while using - split ""
@Salamek
Copy link
Author

Salamek commented Mar 23, 2026

I also ended up accidentally writing a drop-in replacement for WAU in Rust:
https://github.com/Salamek/winget-auto-upgrade

Feature parity currently looks roughly like this:
https://github.com/Salamek/winget-auto-upgrade/blob/master/WAU-COMPARISON.md

I wasn’t sure how long it would take for WAU to implement my proposed changes and ship a new release. Along the way, I also ran into several limitations in WAU that aren’t easily fixable without a significant rewrite of the codebase:

  1. Lack of source awareness
    WAU is not source-aware. Setting WAU_WingetSourceCustom simply replaces the default winget source with another one, effectively disabling updates from all other sources.

My implementation addresses this by being source-aware-deny/allow/override lists can specify the source for a given package ID, and updates across all installed sources are enabled by default (with behavior configurable via lists).

  1. Lack of scope awareness
    While WAU can run in both SYSTEM and USER contexts, it does not provide a way to control which packages should be installed or blocked in each scope.

My implementation introduces scope awareness, allowing deny/allow/override lists to define scope-specific behavior per package ID.

  1. User-context issues
    I fixed a few issues I encountered when running WAU in user context. One notable problem was logging—WAU writes logs to a fixed path inside its installation directory, which is not writable for standard users.

In my implementation, logs are written to %APPDATA% by default (user-specific), with the option to configure a custom path.

Another issue was that the scheduled task in user context needed to be run with “Run with highest privileges”; otherwise, WAU didn’t have sufficient permissions to perform winget upgrade. This may also be related to the logging permission issue mentioned above.

  1. No “mods” system (by design)
    I intentionally did not implement WAU’s “mods” system (i.e., downloading and executing external mod scripts), as it felt somewhat insecure.

Instead, I implemented standard pre_upgrade and post_upgrade hooks that execute arbitrary local executables, with support for parameter templating. This allows running binaries directly without requiring wrapper scripts.

I also plan to create a separate compatibility executable that mimics the mods approach, which can be integrated via these hooks if needed. Is that worth it? I have no idea how often is this feature used.

@Romanitho
Copy link
Owner

Hi @Salamek,

Thanks for the detailed comparison! You've clearly identified the structural limits I wanted to address. I was leaning towards a C# rewrite specifically to implement the WinGet COM API (Microsoft.Management.Deployment) rather than just parsing CLI output.

I have a few questions to see how your project compares:

Under the hood: Does your Rust version use the WinGet COM API directly, or is it a high-performance wrapper around the winget.exe CLI?

Language choice: My concern with Rust is the barrier to entry for the current WAU community, which is mostly composed of Windows SysAdmins familiar with PowerShell/C#. Personally, coming from a strong PowerShell background, I find C# much more aligned with the existing ecosystem and easier for future contributors to maintain.

The Mods: Regarding security, since the Mods folder is in %ProgramFiles%, it's already protected by NTFS permissions. Standard users can't touch it. However, I agree that a 'Hook' system is a cleaner approach for a modern rewrite.

I’m still deciding on the best path forward, but I’m strongly considering sticking with C# for its native integration with Windows APIs and its accessibility for our community.

Let’s keep discussing!

@Salamek
Copy link
Author

Salamek commented Mar 24, 2026

Under the hood:

Before starting, I evaluated three possible approaches to interfacing with WinGet:

  1. Parsing CLI output
  2. Wrapping the PowerShell Microsoft.WinGet.Client (with JSON output) Add a winget list --json microsoft/winget-cli#4965
  3. Using the WinGet COM API (https://github.com/microsoft/winget-cli/blob/master/doc/specs/%23888%20-%20Com%20Api.md))

From what I found:

  • The COM API is still evolving and not yet as widely relied upon in production scenarios
  • CLI usage, while not a formal API, is currently the most practical and commonly used approach
  • I wanted to avoid introducing a PowerShell dependency layer

So I went with option 1 (CLI) as the most pragmatic starting point, with a plan to support all three via a configurable backend:

backend = "cli | ps | com"

The code is structured with this in mind. The implementation does not call winget.exe directly everywhere, instead it uses a trait-based abstraction layer that returns/accepts structured objects (Package, PackageUpgrade, etc.). https://github.com/Salamek/winget-auto-upgrade/blob/master/src/package_manager.rs

At the moment, there are two backends:

  • Native WinGet CLI
  • A stub CLI (used for development on Linux)

Adding a COM backend should be straightforward, Rust has solid Windows bindings via the windows crate, so interoperability is comparable to C/C++.


Language choice

I did consider C#, but one of my main priorities was cross-platform development, since I do most of my work outside Windows VMs.

While .NET is cross-platform, I personally found Rust’s tooling much more straightforward:

  • Minimal setup
  • Consistent project structure
  • Produces a single native executable without extra packaging steps

Example setup is essentially:

winget install Rustlang.Rustup --silent
winget install Microsoft.VisualStudio.2022.Community --silent --override "--wait --quiet --addProductLang En-us --add Microsoft.VisualStudio.Workload.NativeDesktop --includeRecommended"
cargo build --release

That said, I do understand your point about accessibility for the existing WAU community, PowerShell/C# is definitely more familiar in that space. (Rust is already being introduced in parts of Windows, especially where memory safety matters. It’s still early days, but adoption is clearly growing, so I’d consider it a bit of future proofing 🙂 )

I’d frame the tradeoff like this:

  • C# -> better ecosystem alignment and contributor familiarity
  • Rust -> stronger guarantees (memory safety, stricter compile-time checks), simpler deployment (single binary), and cleaner abstraction boundaries, less runtime dependency vs .NET (unless self-contained publish is used)

On contributors: I think familiarity still matters, but tooling (including LLMs) is lowering the barrier a lot, making language choice slightly less restrictive than it used to be. I think i can say that bigger part of future PR's will be created with LLMs help where language wont be that important for contributors. (Like i'm already receiving PRs of good quality (most likely just human checked) that are created by claude...)


Mods system

I may have misunderstood parts of this, but I was under the impression that mods could be auto downloaded and executed from external sources (e.g., URL-based listings).

If that’s not the case, then my concern is less relevant.


C# vs Rust for Windows integration

Rust can integrate with Windows APIs at a similar level to C/C++, using the windows crate, so lack of native access is not limiting factor here.

In worst case scenario, you can use my rust implementation as basic template for your C# version, or i could try to implement COM version backend and decide later...

@Romanitho
Copy link
Owner

Hi @Salamek,

Thanks for the detailed breakdown. Your architectural choice of a 'Backend' abstraction (CLI/PS/COM) is really smart and provides great flexibility.

However, from my perspective with WAU, I feel like we’re at a point where we only have two real paths: either we stay as a PS/Wrapper (simple but fragile), or we jump straight to a C#/COM-API (complex but native). I don’t see much long-term value in building another CLI wrapper, even a fast one, if we’re still parsing text output. That’s why I want to put 100% of my focus on the COM API for WAU 3.0.

Regarding the language, you make a strong point about Rust’s safety and deployment benefits. But for WAU, I believe C# is the right choice for the community. Even if LLMs help with PRs, I still think a human check by someone who understands the code is essential before going to production, and our contributors are much more comfortable with the .NET ecosystem.

I’m currently deep-diving into the COM API 'black box' (testing SYSTEM context, In-Proc vs Out-of-Proc, etc.). It’s a steep learning curve, but it feels like the right 'native' path to make the tool truly robust.

I’ll definitely use your implementation as a blueprint for the source/scope logic, and I’ll adopt a 'Hook' system (pre/post upgrade) as you suggested, as it's much cleaner than the current Mods approach.

Let’s keep 'comparing notes' while we both tackle the COM integration!

Best regards

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@Salamek
Copy link
Author

Salamek commented Mar 26, 2026

@Romanitho Copilot identified issues are out of scope of this PR, but i suggest checking my comments to them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants