Contributing to Winapp2.ini

July 28, 2026 · View on GitHub

This guide covers how to add and update entries in winapp2.ini under the current build workflow.


How Winapp2.ini is maintained

Winapp2.ini is no longer edited directly. Instead, it is assembled from the source files in the Assembler/ directory by winapp2ool.

All contributions must target those source files, not any Winapp2.ini file directly.

Building and publishing are automated. Once your change is merged, a scheduled GitHub Actions workflow rebuilds winapp2.ini and every flavor of it from the current sources, commits the results, and cuts a tagged release with each flavor and its changelog attached. Nobody runs the build by hand, and you never need to generate any output file yourself. Only edit the source files. In practice a merged entry appears in winapp2.ini, and in a release, within a day.


Table of contents

  1. Quick reference
  2. Finding the source of an existing entry
  3. Adding your first entry
  4. Updating an existing entry
  5. Retiring an entry
  6. General rules
  7. Standard entries
  8. Browser entries
  9. UWP entries
  10. EntryBuilder entries
  11. Winapp3.ini
  12. Flavor corrections
  13. How to submit
  14. What happens after you open a PR

Quick reference

What you want to doWhere to edit
Add, update, or remove an entry for a win32-only application (traditional desktop software)Assembler/EntryBuilder/<letter>.ini
Add, update, or remove an entry for an application with a UWP (or UWP and also a win32) version (Windows Store apps, generally)Assembler/UWP/AppInfo/<letter>.ini
Add, update, or remove support for a Chromium-based web browserAssembler/BrowserBuilder/chromium.ini
Add, update, or remove support for a Gecko-based web browserAssembler/BrowserBuilder/gecko.ini
Add a browser entry; Update or remove a generated browser entryAssembler/BrowserBuilder/browser_*.ini
Add, update, or remove an entry for a power-user or aggressive operationWinapp3/Winapp3.ini
Fix an entry that already exists in winapp2.iniFind its source file first. See Finding the source of an existing entry
Retire an entry for software that no longer existsMove it from its source file to Winapp3/Archived entries.ini. See Retiring an entry
Report a flavor-specific issueOpen an issue, or edit the appropriate flavor file in Assembler/<FlavorName>. The <FlavorName> is simply the name of the tool whose flavor you want to modify: CCleaner, CCleaner7, BleachBit, SystemNinja,Tron, or FluentCleaner

All base entries live in Assembler/EntryBuilder/<letter>.ini. Standard winapp2.ini syntax is valid there. The folder name refers to the winapp2ool module that processes it, and an optional shorthand exists but is never required. The files under Assembler/Entries/ are build artifacts regenerated from these sources on every build; do not edit them. See EntryBuilder entries.

Editing a build artifact instead of its source is an easy mistake to make, but it is a mistake. Your committed changes will be silently destroyed when the next build regenerates the artifact from the unmodified source files. CI checks for this: if your PR changes a file under Assembler/Entries/, or a published winapp2.ini or diff.txt file, without also changing the source file that produces it, the generated artifact guard fails and names the source file you should have edited instead. See What happens after you open a PR.


Finding the source of an existing entry

Winapp2.ini is assembled from several source file sets and generators, so many entries do not exist verbatim anywhere in this repository. Searching for a generated entry by name may find nothing. To locate the source of an entry you want to change:

If the entry...Its source is
Is named Browser Name Category * (e.g. Brave Caches *) for a browser described in chromium.ini or gecko.iniGenerated by BrowserBuilder from Assembler/BrowserBuilder/. Fixes for a specific browser go in the browser_*.ini correction files. See Browser entries
Targets paths under %LocalAppData%\Packages\ (Microsoft Store apps)Generated by UWPBuilder from Assembler/UWP/AppInfo/<letter>.ini. See UWP entries
Appears in only one flavor of winapp2.iniAdded by that flavor: Assembler/<FlavorName>/*_additions.ini. See Flavor corrections
Anything elseAssembler/EntryBuilder/<letter>.ini, where <letter> is the first letter of the entry name

Search tip: use GitHub's repository search for the entry name without the trailing *]. A base entry matches twice: its source in Assembler/EntryBuilder/ (edit this one) and its regenerated artifact in Assembler/Entries/ (never edit this one). If only an artifact or a built winapp2.ini matches, the entry is generated. Search for a distinctive fragment of one of its FileKey or RegKey paths to find the generator source.


Adding your first entry

1. Decide what kind of entry you're adding

If the app is...You're addingEdit
A traditional desktop install (.exe, .msi)A standard entryAssembler/EntryBuilder/<letter>.ini
A Microsoft Store app, or has both Store and desktop versionsA UWP entryAssembler/UWP/AppInfo/<letter>.ini
A web browserA browser definitionAssembler/BrowserBuilder/chromium.ini or gecko.ini
An aggressive operation aimed at power usersA Winapp3 entryWinapp3/Winapp3.ini

When in doubt, write a standard entry and place it in the appropriate <letter>.ini file in Assembler/EntryBuilder.

2. Find what to clean

Install the app, use it normally for a while, and do whatever produces the data you want gone: open files, browse around, sign in, run several times, etc. Identify the location of this data on disk. Be careful to make sure that this data isn't comingled with important data such as application configuration.

3. Write the entry

Open the right source file, find the alphabetical spot for your entry, and write it. Follow the Standard entries, UWP entries, or Browser entries section depending on what you're adding. Again, when in doubt, always create a standard entry.

4. Validate

See Verifying your work.

5. Submit

Open a PR against master.


Updating an existing entry

  1. Locate the entry's source.
  2. Make your change in that source file. If the entry lives in Assembler/EntryBuilder/, recall that standard winapp2.ini syntax is still valid there. See EntryBuilder entries.
  3. Validate.
  4. Open a PR describing what changed and why (e.g. "version X moved its cache to a new location").

Retiring an entry

Entries for software that is no longer available are moved to the archive at Winapp3/Archived entries.ini rather than deleted, preserving them for users who still run the software.

  1. Remove the entry from its source file.
  2. Add it to Winapp3/Archived entries.ini in alphabetical order, written in standard winapp2.ini syntax. A base entry written in standard syntax can be moved as-is from its Assembler/EntryBuilder/ source file. If the entry is generated (BrowserBuilder, UWPBuilder, or EntryBuilder shorthand), archive the generated form by copying it from the artifact under Assembler/Entries/ and adding a Skip= key to its source section.
  3. In your PR, note why the software has been archived (e.g. the vendor site is gone or a live service has been discontinued).

General rules

Software availability

Entries are generally accepted for any software currently available for download. Direct vendor downloads are preferred; entries for software only available through download aggregators (e.g. Softonic, Uptodown) will be accepted, but entries are periodically audited, and software no longer available from its original vendor may be moved to the archive at Winapp3/Archived entries.ini (see Retiring an entry).

Categorization

  • Games and directly gaming-related software (launchers, modding tools, ancillary utilities, etc.) must use Section=Games.
  • Web browsers are primarily generated entries. Their categorization is handled in the BrowserInfo section for that browser (see Browser entries).
  • Everything else should use the most appropriate LangSecRef. Prefer LangSecRef over Section when a standard CCleaner category fits. See the table in Standard entries for valid values.

Safety

Entries should clean transient, rebuildable data such as caches, logs, temporary files, recently-used lists or similar. Don't target settings, configurations, or anything a user would expect to survive a clean.


Standard entries

Standard entries cover desktop (Win32) applications that are not web browsers and do not have UWP versions. They use standard winapp2.ini syntax and live in Assembler/EntryBuilder/.

Where to edit

Each file in Assembler/EntryBuilder/ contains entries whose names begin with a particular letter. Add your entry to the file matching the first letter of the entry name. Numbers and symbols go in #.ini.

Entry name

Entry names must end with *]: a space, an asterisk, and a closing bracket. This trailing * is required.

[Application Name *]

Style rules

Run WinappDebug on your entry before submitting to catch style and syntax issues. Many common issues can be automatically repaired by WinappDebug.

RuleDetail
Alphabetical orderEntries must be sorted alphabetically within the file. Numbers and symbols sort before letters.
Key orderWithin each entry: categorization → detection → warnings → deletion. Within a group, keys of the same type come before keys of a different type in alphabetical order by key name (Detect before DetectFile), and keys of the same type are sorted numerically by their index.
Key numberingKeys of the same type are numbered sequentially starting from 1 with no gaps (FileKey1, FileKey2, ...). Detect and DetectFile may omit the 1 in the case that there's only a single key. FileKey, RegKey, and ExcludeKey always have numbers, even when there is only one
No blank lines within an entryA single blank line separates entries from each other. No blank lines inside an entry. Winapp2ool will automatically remove blank lines from inside entries.
No trailing whitespaceLines must not have trailing spaces or tabs.
Use environment variablesAll filesystem paths must use environment variables. Never use hardcoded drive letters.
Comments are welcome where helpfulA comment is a line beginning with ; placed directly above an entry. Use one to record context future maintainers will need, such as why an unusual path is targeted. Comments live permanently in the source files but are stripped from the generated artifacts and the final winapp2.ini.

Valid LangSecRef values

LangSecRef values are defined by CCleaner v6.39 and some (but not all) are supported by other tools. Values marked "CCleaner only" are not supported by other tools and will display the number instead of the CCleaner section heading.

LangSecRefCCleaner sectionNotes
3001Internet ExplorerDeprecated
3005Microsoft Edge (legacy)Deprecated
3006Edge ChromiumCalled Microsoft Edge in BleachBit
3021Applications
3022Internet
3023Multimedia
3024Utilities
3025WindowsCalled Microsoft Windows in BleachBit
3026Firefox
3027Opera
3028Safari
3029Google Chrome
3030Thunderbird
3031Windows Store
3032CCleaner BrowserCCleaner only
3033Vivaldi
3034Brave
3035Opera GXCCleaner only
3036SpotifyCCleaner only
3037Avast Secure BrowserCCleaner only
3038AVG Secure BrowserCCleaner only
3039Arc BrowserCCleaner only
3040iTunesCCleaner only
3042WhatsAppCCleaner only
3043Norton Private BrowserCCleaner only
3044Avira Secure BrowserCCleaner only
Note: 3041 is not a valid LangSecRef value.

Key syntax reference

Categorization

Required (exactly one). Defines the UI category the entry appears under.

Examples
LangSecRef=3021
Section=Games

Detection

At least one Detect or DetectFile key is required.

Detection keys control whether or not an entry is displayed to the user. If at least one detection key matches a path, file, or registry key on the current system, the entry is displayed.

Scope detection keys to the target application as tightly as possible to avoid false positives. You may wish to capture individual versions or all of them, depending on the scope of the entry.

The last path segment of a DetectFile accepts wildcards.

Nested wildcards are not supported by DetectFile in any tool except winapp2ool.

Detect (registry) paths do not support wildcards.

System Ninja does not support wildcards anywhere within a DetectFile.

Examples
Detect1=HKCU\Software\Vendor\AppName
Detect2=HKCU\Software\Vendor\AppName\AppVersion
DetectFile1=%LocalAppData%\Vendor\AppName
DetectFile2=%LocalAppData%\Vendor\AppName\AppVersion\App.exe

Warnings

Optional. Shows a message when the cleaning routine moves from unchecked to checked in the UI. Many users skip them, so keep warnings short and specific.

Not supported by System Ninja or R-Wipe&Clean

Warning=This will delete your saved session data.

Deletion

At least one required. Use FileKey for filesystem paths and RegKey for registry paths.

FileKey Example
FileKey1=%LocalAppData%\App\Temp|*.tmp
FileKey2=%LocalAppData%\App\Cache|*|RECURSE
FileKey3=%LocalAppData%\App\OldVersions|*|REMOVESELF
  • A | separates the path from the pattern.
  • Multiple patterns in one key: FileKey1=%Path%|file1.log;file2.log;*.tmp
  • RECURSE deletes matching files in all subdirectories. In CCleaner, also deletes empty subdirectories when provided *.*
  • REMOVESELF does the same as RECURSE, but always removes empty subdirectories left behind. Implies RECURSE. Will delete the parent folder if it is empty when the clean completes.
RegKey Example
RegKey1=HKCU\Software\App\RecentFiles
RegKey2=HKCU\Software\App\Settings|LastOpenedPath

A |value suffix deletes only that named value, not the key itself.

RegKey does not support wildcards.

Exclusions

Optional. Preserves specific files or registry keys from deletion. Prefer tightening deletion keys over adding exclusions.

ExcludeKey1=FILE|%AppData%\App\|important.db
ExcludeKey2=PATH|%AppData%\App\|*.cfg
ExcludeKey3=REG|HKCU\Software\App\Preserve
  • FILE excludes a specific named file from deletion
  • PATH excludes files matching a wildcard pattern; covers the directory and all subdirectories
  • REG excludes a registry key and all values and subkeys beneath it

ExcludeKey has no RECURSE or REMOVESELF equivalent. Subdirectories are covered by use of the PATH flag.

Complete example

[Example Application *]
LangSecRef=3021
Detect=HKCU\Software\Example\ExampleApp
FileKey1=%LocalAppData%\Example\ExampleApp\Cache|*|REMOVESELF
FileKey2=%LocalAppData%\Example\ExampleApp\Logs|*.log
RegKey1=HKCU\Software\Example\ExampleApp\RecentFiles

Environment variables

All filesystem paths must use environment variables. Never use hardcoded drive letters.

Variables marked with * check both 64-bit and 32-bit locations on 64-bit systems.

Variables marked "CCleaner only" do not expand to anything in other tools and will not work with them. Avoid using CCleaner-only variables in submissions.

VariableWindows Vista–11 pathNotes
%AppData%C:\Users\%UserName%\AppData\Roaming
%CommonAppData%C:\ProgramDataCCleaner only
%CommonProgramFiles%*C:\Program Files\Common Files
%Documents%C:\Users\%UserName%\DocumentsCCleaner only
%LocalAppData%C:\Users\%UserName%\AppData\Local
%LocalLowAppData%C:\Users\%UserName%\AppData\LocalLowCCleaner only
%Music%C:\Users\%UserName%\MusicCCleaner only
%Pictures%C:\Users\%UserName%\PicturesCCleaner only
%ProgramData%C:\ProgramData
%ProgramFiles%*C:\Program Files
%Public%C:\Users\%UserName%\Public
%SystemDrive%C:
%UserProfile%C:\Users\%UserName%
%Video%C:\Users\%UserName%\VideosCCleaner only
%WinDir%C:\Windows

Registry variables

VariableRegistry hive
HKCRHKEY_CLASSES_ROOT
HKCUHKEY_CURRENT_USER
HKLMHKEY_LOCAL_MACHINE
HKUHKEY_USERS
HKCCHKEY_CURRENT_CONFIG

Keys not accepted in contributions

The following keys are valid CCleaner-only syntax but are not used in winapp2.ini and should not appear in submitted entries.

KeyNotes
DefaultControls whether an entry is enabled by default in CCleaner. All winapp2.ini entries are opt-in.
DetectOSLimits an entry to specific Windows versions by kernel number. CCleaner only.
SpecialDetectUses CCleaner's internal application detection patterns. CCleaner only. Deprecated.

Browser entries

Web browser entries are generated automatically by winapp2ool's BrowserBuilder module. Do not add browser entries manually to Assembler/EntryBuilder/. Instead, edit the files in Assembler/BrowserBuilder/.

How BrowserBuilder works

BrowserBuilder reads two files, chromium.ini and gecko.ini, and generates a cleaning entry for every browser/category combination described in them. Each browser is a [BrowserInfo: Browser Name] section. Each cleaning category (Caches, Cookies, History, etc.) is an [EntryScaffold: Category Name] section. BrowserBuilder produces one entry per browser per category.

After generating the base entries, BrowserBuilder applies corrections from the browser flavor files to handle cases where the generated output is wrong or incomplete for specific browsers.

Adding a new browser

To add a new Chromium-based browser, add a [BrowserInfo: Browser Name] section to chromium.ini. For a Gecko-based browser, add to gecko.ini. Place the section alphabetically by browser name within the file.

Required keys

KeyPurpose
Section=The CCleaner section name for all generated entries for this browser. Use the format Browser Name Web Browser to group entries under their own section. Sections beginning with a number will fail to display correctly in CCleaner. Prepend them with a . eg. .360 Secure Web Browser
UserDataPath=The filesystem path to the directory containing the browser's user profile data. For Chromium browsers this is the User Data folder. For Gecko browsers this is the Profiles folder. This path is also used to generate a DetectFile for every entry.

Optional keys

KeyPurpose
RegistryRoot=The registry root key for this browser. Multiple values can be provided on separate lines. If omitted, RegKeys won't be created and EntryScaffolds carrying a RequiresRegistryRoot key will skip this browser.
TruncateDetect=Provide this key (any value) to strip \User Data\ from the generated DetectFile. Required when the UserDataPath contains a wildcard in the direct parent directory name. This value appears boolean but it is not, provide this key if and only if you want the DetectFile truncated.
Skip=Provide this key (any value) to exclude this browser from generation. Used to retire support without losing the configuration. This value appears boolean but it is not, provide this key if and only if you want the entry skipped

Multiple UserDataPath= and RegistryRoot= values are supported; list them as separate keys.

Style rules

RuleDetail
Section name formatMust be [BrowserInfo: Browser Name] exactly.
Alphabetical orderSections must be sorted alphabetically by browser name within the file.
No trailing whitespaceLines must not have trailing spaces or tabs.

Chromium example

[BrowserInfo: Example Browser]
Section=Example Web Browser
UserDataPath=%LocalAppData%\Example\ExampleBrowser\User Data
RegistryRoot=HKCU\Software\Example\ExampleBrowser
[BrowserInfo: Example Browser 2]
Section=Example Web Browser 2
UserDataPath=%LocalAppData%\RegistryLess\Browser\User Data

TruncateDetect Example

When a TruncateDetect key is provided, BrowserBuilder drops the last directory in the generated DetectFile to avoid problems with the CCleaner DetectFile parser.

Note: DetectFile keys containing a wildcard generated with TruncateDetect are still incompatible with System Ninja due to System Ninja not supporting wildcards in DetectFile.

[BrowserInfo: Brave]
Section=Brave Web Browser
TruncateDetect=True
UserDataPath=%LocalAppData%\BraveSoftware\Brave-Browser*\User Data
RegistryRoot=HKCU\Software\BraveSoftware\Brave-Browser
RegistryRoot=HKCU\Software\BraveSoftware\Brave-Browser-Beta
RegistryRoot=HKCU\Software\BraveSoftware\Brave-Browser-Nightly
Generated DetectFile
DetectFile=%LocalAppData%\BraveSoftware\Brave-Browser*

Gecko-specific variables

Gecko's gecko.ini supports an additional inferred variable in EntryScaffold patterns:

  • %LocalDataPath%: Gecko profile user data is stored in a folder located within %AppData%. Cache data is stored in a folder by the same name in %LocalAppData%. The %LocalAppData% path is inferred from %UserDataPath%.

This is handled automatically and requires no action from contributors adding a Gecko browser.

Applying corrections to generated browser entries

Generated entries aren't always right for every browser. The correction files let you fix or extend individual entries without touching the scaffolds.

Section names in correction files must exactly match the generated entry name, which follows the pattern Browser Name Category * (e.g. Brave Caches *).

BrowserBuilder corrections use the same Flavorize winapp2ool module as the tool-specific flavors. These files live in /Assembler/BrowserBuilder/

When to use each file

FileUse when
1. browser_section_removals.iniAn entire generated entry does not apply to a specific browser.
2. browser_name_removals.iniA specific key name should be removed from a browser's entry. Number-sensitive match, key numbers must match. (eg. FileKey3= won't remove FileKey1=)
3. browser_value_removals.iniA specific key value is wrong for a browser regardless of which numbered key it appears on. Write the key with the target value; the number you give it is irrelevant. (eg. FileKey=some\path
4. browser_section_replacements.iniThe generated entry for a browser is so different from the default that it needs to be replaced entirely.
5. browser_key_replacements.iniA specific key needs a different value for a browser (exact name and section match).
6. browser_additions.iniA browser needs extra keys beyond what the scaffold generates, or needs an entirely new entry that BrowserBuilder does not produce.

Style rules for correction files

RuleDetail
Section name must match exactlyThe section name must match the generated entry name precisely, including the *] suffix.
Include a commentAdd a brief comment above each correction explaining why it is needed. A comment is a line which begins with ; and appears directly above an entry.
Keys only in the right filesbrowser_section_removals.ini ignores key content. Only the section name matters. browser_name_removals.ini ignores key values. Only the name matters. Follow each file's rules.
No trailing whitespaceLines must not have trailing spaces or tabs.

Addition example

; Example Browser stores crash reports in a non-standard location not covered by the scaffold
[Example Browser Telemetry *]
FileKey1=%LocalAppData%\Example\ExampleBrowser\CrashReports|*|REMOVESELF

Section removal example

Section removals are performed on a name-only basis and need not contain any keys. Any provided keys will be ignored.

; Example Browser does not support pinned tabs
[Example Browser Pinned Tabs *]

Adding new EntryScaffolds

Adding a new EntryScaffold (a new cleaning category applied across all browsers) is possible. New scaffolds must be consistent: if the data exists across all browsers, the scaffold should generate correct entries for all of them, or corrections must be provided for browsers where it does not apply.

Every EntryScaffold section name must follow the format [EntryScaffold: Category Name]. The category name is appended to the browser name: [EntryScaffold: Example Category] produces entries named Browser Name Example Category *.

Keys

KeyPurpose
FileKeyBase=A FileKey template. BrowserBuilder substitutes browser-specific variables and adds the result as a numbered FileKey in the generated entry. Multiple values are supported; list them as separate keys.
RegKeyBase=A RegKey template. BrowserBuilder substitutes %RegistryRoot% and adds the result as a numbered RegKey. Multiple values are supported.
RequiresRegistryRoot=BrowserBuilder skips this scaffold for any browser without a RegistryRoot= key.

A scaffold with neither FileKeyBase= nor RegKeyBase= produces no output.

Variables

Each template variable resolves to a value from the browser's BrowserInfo section.

VariableAvailable inExpands to
%UserDataPath%FileKeyBaseThe browser's user data directory, as declared by UserDataPath= in its BrowserInfo section.
%BrowserPath%FileKeyBaseThe parent directory of %UserDataPath%. For Chromium browsers, also generates a second FileKey with the path mirrored under %ProgramFiles%.
%LocalDataPath%FileKeyBase (Gecko only)The cache directory inferred from %UserDataPath% by substituting %LocalAppData% for %AppData%.
%RegistryRoot%RegKeyBaseThe browser's registry root path, as declared by RegistryRoot= in its BrowserInfo section. Expands once per RegistryRoot= value, producing one RegKey per root.

Example

[BrowserInfo: Example Browser]
Section=Example Web Browser
UserDataPath=%AppData%\Example Browser\User Data
RegistryRoot=HKCU\Software\ExampleBrowser


[EntryScaffold: Example Category]
FileKeyBase=%UserDataPath%\*\ExampleData|*|REMOVESELF
FileKeyBase=%BrowserPath%\Application|example.log
RegKeyBase=%RegistryRoot%\ExampleKey
[Example Browser Example Category *]
Section=Example Web Browser
FileKey1=%AppData%\Example Browser\User Data\ExampleData|*|REMOVESELF
FileKey2=%AppData%\Example Browser\Application|example.log
RegKey1=HKCU\Software\ExampleBrowser\ExampleKey

UWP entries

UWP entries cover Universal Windows Platform applications generally installed from the Microsoft Store. They are generated by winapp2ool's UWPBuilder module and live in Assembler/UWP/AppInfo/.

How UWPBuilder works

UWPBuilder reads Assembler/UWP/UWP.ini (the baseline cleaning scaffold applied to every UWP app) alongside all 27 alphabetical AppInfo files. For each application, it generates a complete winapp2.ini entry by combining the scaffold's FileKeyBase patterns with app-specific keys, substituting the app's package folder name wherever %Package% appears.

[EntryScaffold: UWP App]
DetectFileBase=%Package%
FileKeyBase=%Package%\AC|*|RECURSE
FileKeyBase=%Package%\Settings|*.log*
FileKeyBase=%Package%\SystemAppData\Helium|*.log*
FileKeyBase=%Package%\TempState|*|REMOVESELF

The baseline scaffold above targets the standard UWP storage locations present in nearly every UWP application:

  • \AC\: Application cache
  • \Settings\*.log*: Settings logs
  • \SystemAppData\Helium\*.log*: Helium logs
  • \TempState\: Temporary state

Likewise, it also creates one DetectFile per provided package.

UWPBuilder adds app-specific keys after the scaffold keys.

Where to edit

Add your entry to Assembler/UWP/AppInfo/<letter>.ini, where <letter> is the first letter of the application name. Numbers and symbols go in #.ini.

Finding the package folder name

The package folder name is the value for the Package= key. It is the name of the application's folder under %LocalAppData%\Packages\. You can find it by:

  • Browsing %LocalAppData%\Packages\ in Explorer and looking for a folder matching the application name.
  • Running Get-AppxPackage | Where-Object {$_.Name -like "*AppNameHere*"} in PowerShell. The PackageFamilyName field gives you the folder name.

For multi-package applications, list each package folder separately as Package1=, Package2=, etc.

Style rules

RuleDetail
Section name formatMust be [Application Name *] the trailing * is required. This is the name that the generated entry will have.
Alphabetical orderEntries must be sorted alphabetically within the file.
CategorizationExactly one of LangSecRef= or Section= is required. Use Section=Games for games and gaming-related apps.
Package keyAt least one Package= key is required. Single-package apps use Package=. Multi-package apps use Package1=, Package2=, etc.
No trailing whitespaceLines must not have trailing spaces or tabs.
No blank lines within an entryA single blank line separates entries from each other.

Supported keys

KeyRequiredPurpose
Package=Yes (at least one)Package folder name under %LocalAppData%\Packages\.
LangSecRef= or Section=Yes (exactly one)Categorization.
Detect=, Detect1, Detect2=, ...NoAdditional registry detection criteria. Passed through verbatim and renumbered.
DetectFile=NoAdditional filesystem detection criteria. Useful for hybrid win32+UWP apps. Each package folder is always generated as a DetectFile due to the root UWP.ini's scaffold containing DetectFileBase=%Package%
FileKeyBase=NoApp-specific FileKey templates using %Package% or %PackageN% variables. Added after the scaffold keys. This is a stylistic choice only, and providing a FileKey will also work.
FileKey=NoStandard winapp2.ini FileKey targeting win32 or non-package locations. Can also use %Package% variables. This is a stylistic choice only, and providing a FileKeyBase will also work.
RegKey=NoStandard winapp2.ini RegKey. Passed through verbatim and renumbered.
ExcludeKey=NoStandard winapp2.ini ExcludeKey. Can use %Package% variables.
Skip=NoProvide this key (any value) to exclude the app from generation without removing its configuration. This value appears boolean but it is not, provide this key if and only if you want the entry skipped

The %Package% variable

In FileKeyBase=, FileKey=, and ExcludeKey= values, %Package% expands to the full path %LocalAppData%\Packages\<PackageFolderName> in the generated output.

For multi-package apps, %Package% expands to each of the packages. Use %Package1%, %Package2%, etc. to target a specific package.

Single-package example

UWP AppInfo Input
[Example UWP App *]
LangSecRef=3024
Package=ExampleCorp.ExampleApp_abc123xyz
FileKeyBase=%Package%\LocalCache\Local\Logs|*.log
UWPBuilder output (after linting)
[Example UWP App *]
LangSecRef=3024
DetectFile=%LocalAppData%\Packages\ExampleCorp.ExampleApp_abc123xyz
FileKey1=%LocalAppData%\Packages\ExampleCorp.ExampleApp_abc123xyz\AC|*|RECURSE
FileKey2=%LocalAppData%\Packages\ExampleCorp.ExampleApp_abc123xyz\LocalCache\Local\Logs|*.log
FileKey3=%LocalAppData%\Packages\ExampleCorp.ExampleApp_abc123xyz\Settings|*.log*
FileKey4=%LocalAppData%\Packages\ExampleCorp.ExampleApp_abc123xyz\SystemAppData\Helium|*.log*
FileKey5=%LocalAppData%\Packages\ExampleCorp.ExampleApp_abc123xyz\TempState|*|REMOVESELF

Multi-package example

UWP AppInfo Input
[Multi-Package App *]
LangSecRef=3021
Package1=Vendor.AppCore_abc123
Package2=Vendor.AppService_def456
FileKeyBase=%Package%\LocalCache\Local\Logs|*.log
FileKeyBase=%Package2%\LocalState\Logs|*.log
FileKey=%ProgramData%\Vendor\AppService\Logs|*
UWPBuilder output (after linting)
[Multi-Package App *]
LangSecRef=3021
DetectFile1=%LocalAppData%\Packages\Vendor.AppCore_abc123
DetectFile2=%LocalAppData%\Packages\Vendor.AppService_def456
FileKey1=%LocalAppData%\Packages\Vendor.AppCore_abc123\AC|*|RECURSE
FileKey2=%LocalAppData%\Packages\Vendor.AppCore_abc123\LocalCache\Local\Logs|*.log
FileKey3=%LocalAppData%\Packages\Vendor.AppCore_abc123\Settings|*.log*
FileKey4=%LocalAppData%\Packages\Vendor.AppCore_abc123\SystemAppData\Helium|*.log*
FileKey5=%LocalAppData%\Packages\Vendor.AppCore_abc123\TempState|*|REMOVESELF
FileKey6=%LocalAppData%\Packages\Vendor.AppService_def456\AC|*|RECURSE
FileKey7=%LocalAppData%\Packages\Vendor.AppService_def456\LocalCache\Local\Logs|*.log
FileKey8=%LocalAppData%\Packages\Vendor.AppService_def456\LocalState\Logs|*.log
FileKey9=%LocalAppData%\Packages\Vendor.AppService_def456\Settings|*.log*
FileKey10=%LocalAppData%\Packages\Vendor.AppService_def456\SystemAppData\Helium|*.log*
FileKey11=%LocalAppData%\Packages\Vendor.AppService_def456\TempState|*|REMOVESELF
FileKey12=%ProgramData%\Vendor\AppService\Logs|*

This generates DetectFile entries for both packages. The scaffold is applied once per package. %Package2% targets only the second package in the app-specific FileKey.

Hybrid win32 + UWP example

Some applications have both a traditional desktop (Win32) installer and a Microsoft Store (UWP) release. Winapp2.ini bundles these into a single entry generated through the UWP process. Win32-targeted paths use FileKey= alongside the package-targeted FileKeyBase= entries.

UWP AppInfo Input
[Hybrid App *]
LangSecRef=3021
Package=Vendor.HybridApp_ghi789
DetectFile=%LocalAppData%\Vendor\HybridApp
FileKeyBase=%Package%\LocalState\Cache|*|RECURSE
FileKey=%LocalAppData%\Vendor\HybridApp\Cache|*|RECURSE
FileKey=%LocalAppData%\Vendor\HybridApp\Logs|*.log
UWPBuilder Output
[Hybrid App *]
LangSecRef=3021
DetectFile1=%LocalAppData%\Packages\Vendor.HybridApp_ghi789
DetectFile2=%LocalAppData%\Vendor\HybridApp
FileKey1=%LocalAppData%\Packages\Vendor.HybridApp_ghi789\AC|*|RECURSE
FileKey2=%LocalAppData%\Packages\Vendor.HybridApp_ghi789\LocalState\Cache|*|RECURSE
FileKey3=%LocalAppData%\Packages\Vendor.HybridApp_ghi789\Settings|*.log*
FileKey4=%LocalAppData%\Packages\Vendor.HybridApp_ghi789\SystemAppData\Helium|*.log*
FileKey5=%LocalAppData%\Packages\Vendor.HybridApp_ghi789\TempState|*|REMOVESELF
FileKey6=%LocalAppData%\Vendor\HybridApp\Cache|*|RECURSE
FileKey7=%LocalAppData%\Vendor\HybridApp\Logs|*.log

EntryBuilder entries

EntryBuilder is the winapp2ool module that turns the base entry sources in Assembler/EntryBuilder/<letter>.ini into the artifacts in Assembler/Entries/. Every base entry lives in an EntryBuilder source file. Standard winapp2.ini syntax passes through generation unchanged, so for most contributions the folder is simply where base entries live; an optional shorthand DSL is additionally available.

You do not need to learn the shorthand to contribute.

  • Adding an entry? Write a standard entry in Assembler/EntryBuilder/<letter>.ini. When in doubt, always contribute standard syntax. If shorthand would benefit the entry, maintainers will help convert it during review.
  • Fixing an existing entry? Edit its source in Assembler/EntryBuilder/, in standard syntax. Any valid winapp2.ini key passes through EntryBuilder unchanged. Leave any shorthand keys you don't recognize as they are rather than rewriting them.
  • Want to use the shorthand? Welcome, but never required. The EntryBuilder readme documents the full DSL: list variables with <Name> token fan-out, and scaffold families for applications embedding WebView2 or QtWebEngine.

The Scaffolds directory

Assembler/Scaffolds/ holds shared catalogs of cleaning patterns (webview.ini, qtwebengine.ini) drawn on by EntryBuilder and UWPBuilder. A change to a scaffold catalog affects every entry that uses it. Open an issue before editing these files.


Winapp3.ini

Winapp3/Winapp3.ini is an extension to winapp2.ini for power users. It uses identical syntax to standard winapp2.ini entries. Entries target operations that are more aggressive, broader in scope, or otherwise carry a higher risk of unintended data loss than entries in the main database. Users should understand what an entry does before enabling it.

Contributions to Winapp3.ini are subject to additional scrutiny. Entries must be clearly scoped, accurately described, and appropriate for a knowing power user. Include a Warning= key for entries that could affect application functionality.

Edit Winapp3/Winapp3.ini directly. The same style rules as standard entries apply.


Flavor corrections

Flavors are custom builds of winapp2.ini with certain tweaks applied to make it more compatible with particular tools.

Each flavor is built by applying a set of Transmute operations (structured changes in the form of additions, removals, and substitutions) to the base file. Correction files for each flavor live in Assembler/<FlavorName>/. If you find a flavor-specific problem or shortcoming, you can submit changes to these files or open an issue.

Each flavor directory contains the same six file types:

FileWhat it does
*_section_removals.iniRemoves entire entries from the flavor output.
*_name_removals.iniRemoves specific keys from entries by key name (number-sensitive).
*_value_removals.iniRemoves specific keys from entries by exact value match (number-insensitive).
*_section_replacements.iniReplaces entire entries in the flavor output.
*_key_replacements.iniReplaces specific keys in entries.
*_additions.iniAdds new entries or appends keys to existing entries.

Corrections are applied in the order listed above. The same style rules apply as for the equivalent browser correction files: section names must exactly match the target entry name. Comments are helpful in the flavor files and will not be compiled into the final winapp2.ini.

Some flavor files also contain sections named [*] or [*Map: label]. These are Transmute global operations: rules applied against every entry in the file rather than one named section (for example, remapping browser Section= values to their CCleaner LangSecRef numbers across all generated browser entries). Leave these sections alone unless you understand how they work. See the Transmute readme for the full specification.


How to submit

Pull request: The preferred method. Fork the repository, make your changes to the appropriate source files in Assembler/, Winapp3/, or wherever relevant, and open a pull request against the master branch. Describe what changed and why.

No git experience? You can contribute entirely from your browser: navigate to the source file on GitHub, click the pencil icon ("Edit this file"), make your change, and choose "Propose changes". GitHub creates the fork and the pull request for you. Most contributions are single-file edits, and this workflow handles them fine.

Issue: If you found a problem but aren't comfortable making the change yourself, an issue works just as well. Include enough detail (application name, affected paths, what is wrong or missing) for maintainers to act on it.

What to include in your PR

Commit source files only. Do not include build outputs:

  • any flavor of winapp2.ini, or any diff.txt
  • anything under Assembler/Entries/: every file there opens with a header saying DO NOT EDIT THIS FILE DIRECTLY and naming its source

The build regenerates all of these files from your source change after it merges.

The reliable way to do this is to stage your source files by name:

git add "Assembler/EntryBuilder/A.ini"
git commit -m "add an entry for Example App"

Avoid git add -A and git add ..

If you ran the full build to check your work, your working copy now contains 29 regenerated artifacts plus all seven rebuilt published outputs.

The generated artifact guard will tell you, and git restore on the files it names will fix it

Verifying your work

This is entirely optional, and you can open a PR without doing any of it. CI builds your PR and reports back, and a maintainer reviews it either way.

Everything below requires winapp2ool. It is also attached to every release.

If you edited a generator's source files, regenerate its output before linting. In every case, finish by running WinappDebug on the file in the last column:

You editedGenerate withMenu pathFile to lint
Assembler/EntryBuilder/<letter>.iniEntryBuilder6 (Entry Lab), then 3entrybuilder.ini
Assembler/BrowserBuilder/...BrowserBuilder6 (Entry Lab), then 1browsers.ini
Assembler/UWP/AppInfo/<letter>.iniUWPBuilder6 (Entry Lab), then 2uwp.ini

Each builder's README covers usage in depth.

Launch Winapp2ool and input 1 to open WinappDebug. Point it at the file from the table above. A single source file or generated output works directly; you do not need a built winapp2.ini. Make any corrections necessary (or allow WinappDebug to make them if possible) such that your entries do not cause any errors. WinappDebug is a static analysis tool that catches and repairs a wide variety of style and syntax issues in winapp2.ini. See the WinappDebug README (linked above) for usage guidance.

Running the full build

CI runs this on every PR, but you can run it locally too

  1. Clone the repo. The build script runs from the Assembler/ directory and finds and places each flavor of winapp2.ini via relative paths; it will fail without the surrounding directory structure.
  2. Make your changes to the source files.
  3. Run & '.\build winapp2.ps1' from PowerShell in Assembler/. If you get an execution policy error, run Set-ExecutionPolicy -Scope Process RemoteSigned. A clone already contains the winapp2ool.exe the script needs.
  4. Open the built winapp2.ini (each flavor is written to its home location) and check that your entry is there and looks the way you expected.
  5. Optionally, drop the built winapp2.ini into a cleaning tool and scan with it to confirm your entry targets what you expected and nothing else. Then run the clean and verify that what should survive did.

The build rewrites all 29 artifacts under Assembler/Entries/ and all seven published output files in your working copy. Rather than cleaning that up afterwards, stage your source files by name and ignore the rest.

& '.\build winapp2.ps1' -Verify is the maintainer-side variant: it builds nothing, regenerating every artifact into a scratch folder and byte-comparing against the committed Assembler/Entries/ files instead, and failing on any mismatch. CI runs it automatically on every push to catch artifacts that have drifted from their sources (e.g. bad generator output).


What happens after you open a PR

Two automated checks run against your pull request. Neither needs anything from you beyond the PR itself, and a maintainer always reviews your change.

The generated artifact guard

Runs on every PR. It checks one thing: that you edited sources rather than build output. It runs in a few seconds

It fails if your PR changes a generated file without changing the source that produces it. When it fails, it marks the offending files directly in the Files changed tab, each with a message naming the source file to edit instead:

Assembler/Entries/A.ini generated by EntryBuilder; edit Assembler/EntryBuilder/A.ini instead

To fix it, move your edit into the named source file and git restore the generated one. You never need to run winapp2ool or regenerate anything to make this check pass.

The PR build

If your PR touches anything under Assembler/, a bot builds winapp2.ini twice: once from master alone, then again with your change merged in, and posts a single comment that it updates on each push. It tells you one of:

  • The PR builds cleanly, followed by the changelog your change produces. Read it as a description of what your change does to the published file, and check it matches what you intended.
  • The build failed, with the output showing where. Usually a syntax error in an edited source file.
  • The PR no longer merges cleanly with master, which you fix by updating your branch.

PRs that only touch Winapp3/ get no build comment. Winapp3.ini is not assembled by the build, so there is nothing to build. That is expected, not a problem with your PR.

After merge

You don't need to do anything else. A scheduled workflow rebuilds winapp2.ini and every flavor from the updated sources, commits the results, and publishes a tagged release with each flavor and its changelog attached. Typically, this is within a day of your merge.